fde-framework 0.1.45__tar.gz → 0.1.47__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.
- {fde_framework-0.1.45 → fde_framework-0.1.47}/CHANGELOG.md +101 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/PKG-INFO +65 -90
- {fde_framework-0.1.45 → fde_framework-0.1.47}/README.md +63 -89
- {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/invoice-extraction/README.md +6 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/ocr-pipeline.plain.py.j2 +17 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/ocr-pipeline.tesseract.py.j2 +12 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/pyproject.toml +2 -2
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/cli.py +76 -23
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/emit.py +127 -9
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/factlog.py +15 -3
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/implement.py +14 -2
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/mcp_server.py +31 -9
- fde_framework-0.1.47/src/fde/report.py +203 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/sandbox.py +85 -19
- fde_framework-0.1.47/tests/test_assets.py +37 -0
- fde_framework-0.1.47/tests/test_build_receipt.py +205 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_implement.py +32 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_mcp.py +32 -0
- fde_framework-0.1.47/tests/test_report.py +80 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_sandbox.py +32 -10
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_sanitisation.py +24 -3
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stop.py +30 -0
- fde_framework-0.1.45/tests/test_build_receipt.py +0 -105
- {fde_framework-0.1.45 → fde_framework-0.1.47}/.gitignore +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/LICENSE +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/policy-qa/README.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/support-triage/README.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/ansible-playbook.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/assisted-deterministic.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/audit-only.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/boundary-and-audit.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/cascade.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/classical-ml.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/compose.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/decision-log.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/deterministic-masking.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/deterministic.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/direct-call.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/episodic-store.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/explainability-record.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/field-match.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/finetune.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/fixed-sequence.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/gitops.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/governed-tools.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/graph-expanded-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/graph-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/hybrid-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/judged.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/keyword-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/kubernetes-manifests.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/labelled-decision.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/labelled-metrics.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm-extraction.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm-scrubbing.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/local-embedding.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/managed-api.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/managed-embedding.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/manual-runbook.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/model-planner.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/ocr-pipeline.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/optimisation-reasoning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/optimisation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/passthrough.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/reranked-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/role-scoped-authority.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/segmentation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/self-hosted.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/serverless-gpu.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/speech-transcription.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/structured-logs.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/systemd-unit.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/terraform-module.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/text-extraction.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/traced.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/vector-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/video-ingestion.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/windowed-ingestion.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/working-state.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/churn-scoring.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/route-planning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/structured-extraction.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/studio-style.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/accountability.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/deployment.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/embedding.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/evaluation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/governance.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/integration.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/memory.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/observability.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/perception.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/planning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/provisioning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/reasoning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/redaction.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/representation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/serving.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/accelerator.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/access_model.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/arrival_rate.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/availability_target.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/cheap_path_coverage.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/confidence_calibrated.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/container_competence.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/corpus_churn.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/corpus_size.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/data_residency.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/environment_lifetime.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/existing_cluster.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/existing_iac_tool.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/external_systems.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/hosting.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/human_waiting.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/input_format.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/interpretability_required.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/labelled_count.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/latency_budget_ms.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/licence_posture.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/operates_after_handover.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/output_shape.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/provisioning_api.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/query_pattern.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/recall_span.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/sensitivity_present.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Generator.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Guard.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Mapper.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/ModelServer.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Parser.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Planner.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Retriever.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Scorer.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Store.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/ToolBoundary.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Tracer.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/locales/eu-gdpr.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/locales/in-dpdp.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/ansible-playbook.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/assisted-deterministic.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/audit-only.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/boundary-and-audit.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-reasoning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-representation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/classical-ml-reasoning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/classical-ml.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/compose.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/decision-log.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/deterministic-masking.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/deterministic.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/direct-call.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/episodic-store.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/explainability-record.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/field-match.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/finetune-representation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/finetune.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/fixed-sequence.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/gitops.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/governed-tools.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/graph-expanded-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/graph-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/hybrid-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/judged.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/keyword-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/kubernetes-manifests.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/labelled-decision.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/labelled-metrics.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm-representation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm-scrubbing.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/local-embedding.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/managed-api.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/managed-embedding.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/manual-runbook.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/model-planner.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/ocr-pipeline.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/optimisation-reasoning.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/optimisation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/passthrough.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/reranked-retrieval.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/role-scoped-authority.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/segmentation.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/self-hosted.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/serverless-gpu.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/speech-transcription.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/structured-logs.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/systemd-unit.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/terraform-module.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/text-extraction.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/traced.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/vector-search.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/video-ingestion.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/windowed-ingestion.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/working-state.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/langgraph.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/llamaindex.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/local-judge.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/mcp.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/ollama.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/openai-judge.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/opentelemetry.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/ortools.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/peft.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/pgvector.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/plain-python.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/qdrant.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/supermemory.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/tesseract.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/vllm.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/whisper.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/xgboost.md +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/accountability/decision-log.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/accountability/explainability-record.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/compose.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/kubernetes-manifests.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/systemd-unit.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/embedding/local-embedding.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/embedding/managed-embedding.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/field-match.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.local-judge.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.openai-judge.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/labelled-metrics.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/labelled-metrics.xgboost.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/audit-only.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/boundary-and-audit.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/role-scoped-authority.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/direct-call.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/governed-tools.mcp.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/governed-tools.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.pgvector.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.supermemory.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/working-state.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/structured-logs.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/traced.opentelemetry.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/traced.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/passthrough.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/speech-transcription.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/speech-transcription.whisper.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/text-extraction.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/video-ingestion.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/windowed-ingestion.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/fixed-sequence.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/model-planner.langgraph.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/model-planner.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/optimisation.ortools.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/optimisation.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/ansible-playbook.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/gitops.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/manual-runbook.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/terraform-module.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/classical-ml.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/classical-ml.xgboost.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/finetune.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/labelled-decision.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/llm.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/optimisation.ortools.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/optimisation.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/redaction/deterministic-masking.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/redaction/llm-scrubbing.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/assisted.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/classical-ml.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/classical-ml.xgboost.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/deterministic.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/finetune.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/llm.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/segmentation.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.pgvector.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.qdrant.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.pgvector.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.qdrant.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/hybrid-search.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/keyword-search.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/reranked-retrieval.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.llamaindex.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.pgvector.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.qdrant.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/managed-api.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.ollama.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.vllm.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/serverless-gpu.plain.py.j2 +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/__init__.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/architect.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/bench.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/costing.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/debt.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/decide.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/decompose.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/deploy.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/drift.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/evolution.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/experiment.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/forecast.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/gates.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/graph.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/history.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/impact.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/importer.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/__init__.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/answers.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/documents.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/interview.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/llm_reader.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/prose.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/samples.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/lifecycle.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/__init__.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/base.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/fact.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/profile.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/respondent.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/schema.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/moves.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/ops.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/predicate.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/realization.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/registry.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/scan.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/scorecard.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/space.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/stakeholders.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/stop.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/training.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/value.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/workflow.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/__init__.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/conftest.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/models/__init__.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/models/test_profile.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_acceptance.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_access_and_sensitivity.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_answers.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_audit_fixes.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_bench.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cascade.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_engagement.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_evolution.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_gates.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_intake.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_kb.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_robustness.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_samples.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_costing.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_coverage.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_dead_zones.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_debt.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_decide.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_decompose.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_deploy.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_documents.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_drift.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_embedding.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_emit.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_evolution.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_example_transcript.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_experiment.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_factlog.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_finetune.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_finetune_real.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_forecast.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_gates.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_history.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_impact.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_importer.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_interview.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_lifecycle.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_llm_reader.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_locales.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_mcp_stdio.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_memory_retrieval.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_more_templates.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_moves.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_multimodal.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_next.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_ops.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_outcome_contract.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_package.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_prose.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_realization.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_registry.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_release_consistency.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_remaining.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_retrieval_eval.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_reversibility.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_samples.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_scan.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_schema.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_scorecard.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_serving.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_shipped_registry.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_space.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stack_swap.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stakeholders.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_supermemory.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_templates.py +0 -0
- {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_value.py +0 -0
|
@@ -5,6 +5,107 @@ the project is pre-release, so everything sits under 0.1.0 until the first tag.
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.1.47] — 2026-10-12
|
|
9
|
+
|
|
10
|
+
A fifteenth outside reading, the first of the source tree, and a
|
|
11
|
+
sixteenth that ran the invoice example to its harness. Between them:
|
|
12
|
+
a build that refused after writing, an emitter that could leave half a
|
|
13
|
+
project, a sandbox policy the agent could rewrite for the next run, an
|
|
14
|
+
envelope field that assumed a failure wrote nothing -- and an exam that
|
|
15
|
+
could not get past its own pipeline's door.
|
|
16
|
+
|
|
17
|
+
- **A refusal writes nothing.** The locale was checked after the project
|
|
18
|
+
and the prediction records had gone to disk, and the refusal said so:
|
|
19
|
+
"refused after writing code". It is resolved before anything is
|
|
20
|
+
written now, and a test holds the output directory and the record
|
|
21
|
+
unchanged after an unknown pack.
|
|
22
|
+
- **A failed build leaves nothing that looks like a build.** The emitter
|
|
23
|
+
builds in a staging directory beside the destination and moves the
|
|
24
|
+
finished tree into place whole; a writer that fails halfway takes the
|
|
25
|
+
staging directory with it. Pinned by a test that breaks a writer.
|
|
26
|
+
- **The exam reaches the thing it examines.** The invoice example's text
|
|
27
|
+
pairs were refused at the emitted pipeline's own door -- the design's
|
|
28
|
+
first stage read `pages` -- so every golden case scored as an input
|
|
29
|
+
error, the adversarial layer "passed" on refusals, and the build had
|
|
30
|
+
said "wrote". Two changes. The OCR stage now takes already-recognised
|
|
31
|
+
text as input that enters after it, says so in the envelope, and the
|
|
32
|
+
harness counts those cases and prints that the reading stage went
|
|
33
|
+
unexercised: a score on text measures extraction, not OCR. And a build
|
|
34
|
+
whose golden cases cannot enter its own pipeline is refused in staging,
|
|
35
|
+
naming the case and the reason, before anything is written. Pinned by
|
|
36
|
+
a test that builds the invoice example and runs its harness, and one
|
|
37
|
+
that feeds pairs no contract reads.
|
|
38
|
+
- **The sandbox policy can only narrow.** `ops/agent-policy.yaml` lives
|
|
39
|
+
inside the directory the agent writes to. It could grant `network:
|
|
40
|
+
host` with a reason of its own and add a credential to `env_allow`,
|
|
41
|
+
and the next run honoured both. Now the file names the image and
|
|
42
|
+
bounded limits (memory within 64g, cpus within 64, pids within 8192;
|
|
43
|
+
outside them the default applies and the note says so); a network or
|
|
44
|
+
a name beyond the default allowlist is a request the log shows
|
|
45
|
+
ungranted, and only `--allow-network "who: why"` and `--env-allow`
|
|
46
|
+
at the terminal grant them. Names are validated, and names that change
|
|
47
|
+
what a process loads are refused whoever asks. The file is part of the
|
|
48
|
+
implement loop's fence: rewritten, it is restored and the round says
|
|
49
|
+
so; planted where none was, it is removed. Tests for each, including
|
|
50
|
+
the planted file and a policy asking for 900g.
|
|
51
|
+
- **`mutated` is measured.** The envelope said true only on a writing
|
|
52
|
+
tool's exit 0, which assumed a failure had written nothing. The
|
|
53
|
+
record's files are now hashed before and after a writing tool, so a
|
|
54
|
+
write that failed partway and left changes says true. That is a field
|
|
55
|
+
changing meaning, so `schema_version` is 2, as the policy published in
|
|
56
|
+
0.1.45 said it would be; the schema's description says what changed.
|
|
57
|
+
- The sanitisation suite skips, saying why, outside a git checkout: a
|
|
58
|
+
reviewer running the tests from a source archive saw a collection
|
|
59
|
+
error where a skip was the truth.
|
|
60
|
+
- Not done, and said so: splitting `emit.py` and `cli.py`. They are
|
|
61
|
+
large; they are also where every pinned finding lives, and a split
|
|
62
|
+
without a user asking for a change is churn with the same tests.
|
|
63
|
+
|
|
64
|
+
## [0.1.46] — 2026-10-12
|
|
65
|
+
|
|
66
|
+
Three readings in a row asked for the same thing before anything else:
|
|
67
|
+
the decision, as a document a person who never sees the terminal can act
|
|
68
|
+
on. Writing it exposed one more place the record was reading the wrong
|
|
69
|
+
build.
|
|
70
|
+
|
|
71
|
+
- **`fde report`: the decision brief.** One Markdown file read off the
|
|
72
|
+
record, before any build is authorised: the problem as the client
|
|
73
|
+
stated it, where the engagement stands, what the record knows and who
|
|
74
|
+
said it, the outcome contract, the design with its reasons and rejected
|
|
75
|
+
alternatives, what it rests on and what was waived, the decision debt,
|
|
76
|
+
the stop conditions judged against what has been measured, who has been
|
|
77
|
+
heard, and the next decision. The design and the risks are rendered by
|
|
78
|
+
the same functions a build uses for ARCHITECTURE.md and RISKS.md, so
|
|
79
|
+
the brief and a later build say the same thing; the readings that are
|
|
80
|
+
commands are quoted as the terminal prints them, so the brief cannot
|
|
81
|
+
say more than the commands do. Nothing in it is estimated. `--today`
|
|
82
|
+
makes it reproducible to the byte.
|
|
83
|
+
- **The deployment names its build, and the record reads that build.**
|
|
84
|
+
The banking record, read without `--project`, stood at *stopped*: its
|
|
85
|
+
last-built marker named the emitted project, whose card is 0.879 on
|
|
86
|
+
the answered, while the implemented copy beside it -- the one actually
|
|
87
|
+
served, 0.902 -- passed. `fde deployed --project` records which build
|
|
88
|
+
was deployed, and every command that reads a project by default reads
|
|
89
|
+
the deployed one, then the last one built. Refused for a directory that
|
|
90
|
+
is not an emitted project.
|
|
91
|
+
- **The README's front page answers three questions.** What this is, why
|
|
92
|
+
use it, how fast a result shows. The audit-pass story and the
|
|
93
|
+
thirty-line list of what every emission is held to moved verbatim to
|
|
94
|
+
`HISTORY.md`; the four demos are one line each, saying what each
|
|
95
|
+
proved. The claim ladder and the demo table are unchanged.
|
|
96
|
+
- **The pictures say what the code says.** The README banner and the
|
|
97
|
+
social-preview card had carried "seven gates" since before the eighth
|
|
98
|
+
gate shipped in 0.1.30, drawn once by hand; a fourteenth outside
|
|
99
|
+
reading found the banner contradicting the README it headed. They are
|
|
100
|
+
now drawn by `assets/brand.py` from the gate count the gates module
|
|
101
|
+
reports, each image carries its sentence in a PNG text chunk, and a
|
|
102
|
+
test holds the pictures to the code. The site's image alt text said the
|
|
103
|
+
same; corrected.
|
|
104
|
+
- The demo table says what *Stage* is: the record's lifecycle stage,
|
|
105
|
+
computed from evidence, so `production` on the banking row means
|
|
106
|
+
deployed, attested and journalled -- on a laptop, as the record says --
|
|
107
|
+
not production reliability, which the claim ladder keeps unverified.
|
|
108
|
+
|
|
8
109
|
## [0.1.45] — 2026-10-11
|
|
9
110
|
|
|
10
111
|
A twelfth outside reading, and a coding agent driving the server for the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fde-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.47
|
|
4
4
|
Summary: The decision before the AI build: evidence in, an architecture with receipts out, a scored build or a stop. For Forward Deployed Engineers and anyone deciding whether an AI system should exist.
|
|
5
5
|
Project-URL: Homepage, https://github.com/atulkapoor/fde-framework
|
|
6
6
|
Project-URL: Documentation, https://atulkapoor.github.io/fde-framework/
|
|
@@ -31,6 +31,7 @@ Requires-Dist: pypdf>=4; extra == 'all'
|
|
|
31
31
|
Requires-Dist: python-docx>=1; extra == 'all'
|
|
32
32
|
Provides-Extra: dev
|
|
33
33
|
Requires-Dist: mcp<3,>=2; extra == 'dev'
|
|
34
|
+
Requires-Dist: pillow>=10; extra == 'dev'
|
|
34
35
|
Requires-Dist: pytest>=8; extra == 'dev'
|
|
35
36
|
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
36
37
|
Provides-Extra: documents
|
|
@@ -89,6 +90,7 @@ pip install fde-framework
|
|
|
89
90
|
fde start acme --statement "Extract fields from supplier invoices."
|
|
90
91
|
fde ask acme --role admin # role-scoped discovery interview
|
|
91
92
|
fde architect acme # topology + chosen approaches (rationale lands in ARCHITECTURE.md)
|
|
93
|
+
fde report acme # the decision brief, for whoever has to act on it and is not here
|
|
92
94
|
fde build acme --out project # refuses: eight gates guard the build
|
|
93
95
|
# ...verify data access, capture the baseline, name the eval owner (each gate prints its remedy), then:
|
|
94
96
|
fde build acme --out project # code + evals + deploy assets + runbook
|
|
@@ -158,11 +160,13 @@ It serves `triage`, `start`, `frame`, `status`, `next`, `stage`, `debt`,
|
|
|
158
160
|
`stop_when` and `history`, each returning exactly what the terminal prints,
|
|
159
161
|
refusals included, beside a small envelope an agent can branch on without
|
|
160
162
|
parsing prose: `schema_version`, `status` (ok, blocked, refused, failed),
|
|
161
|
-
`mutated`, and the workspace. The
|
|
162
|
-
never a reading of its text
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
163
|
+
`mutated`, and the workspace. The status follows the command's exit,
|
|
164
|
+
never a reading of its text; `mutated` is measured, the record's files
|
|
165
|
+
hashed before and after, so a write that failed partway and left changes
|
|
166
|
+
says so. Its contract is a JSON Schema, `fde mcp --schema`, that every
|
|
167
|
+
reply is tested against; a client pins `schema_version`, which moves
|
|
168
|
+
only when a field changes meaning or goes away, never when one is added
|
|
169
|
+
(it moved to 2 when `mutated` became a measurement). An engagement is named as `start` named
|
|
166
170
|
it (`start(name="acme")`, then `status(engagement="acme")`), or by its
|
|
167
171
|
path. An agent is not a person, so every path it supplies must stay
|
|
168
172
|
inside one workspace, the directory the server started in or
|
|
@@ -241,7 +245,7 @@ ladder, so nothing here can be over-read:
|
|
|
241
245
|
|
|
242
246
|
| Claim | Status | The evidence, and where it stops |
|
|
243
247
|
|---|---|---|
|
|
244
|
-
| The framework is implemented | verified | 1,
|
|
248
|
+
| The framework is implemented | verified | 1,328 tests on three Pythons in CI; lint clean; every audit finding pinned as a check before it was fixed; every release installed from the published wheel into a fresh interpreter and walked through the first five minutes |
|
|
245
249
|
| A build is reproducible | verified | byte-identical rebuild pinned by test; each public demo carries a Reproduce section and its digests |
|
|
246
250
|
| The decisions generalise | partial | four shapes (extraction, freeform QA, a labelled decision, seventy-seven-way routing) on real data; one industry set; `fde kb sweep` names the shapes nothing serves |
|
|
247
251
|
| The deliverable is production-reliable | unverified | no production engagement; the banking operating loop ran on a laptop and its record says so |
|
|
@@ -251,54 +255,30 @@ ladder, so nothing here can be over-read:
|
|
|
251
255
|
|
|
252
256
|
**Demonstrated**: four complete engagements have run end to end on real
|
|
253
257
|
data, all public with every refusal preserved.
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
[fde-demo-complaints](https://github.com/atulkapoor/fde-demo-complaints)
|
|
260
|
-
2,034 real consumer complaints through the decision shape: the exam
|
|
261
|
-
refused ambiguous ground truth before it existed, the
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
stopping short -- a mis-specified baseline, an in-sample exam, a training
|
|
279
|
-
recipe that trained unshuffled on a prompt it never served -- and 0.1.23
|
|
280
|
-
answered again the same way. 0.1.24 then ran the fine-tuning recipe for
|
|
281
|
-
real on a small base model: the adapter learned the house style on cases
|
|
282
|
-
it never saw, and the six defects that run exposed in the harness, the
|
|
283
|
-
serving path and the comparison are fixed and pinned. An eighth pass gave
|
|
284
|
-
the decision shape its first sign-off, with conditions, and 0.1.25 met
|
|
285
|
-
them: probes on typical cases, label phrases rather than words, a merge
|
|
286
|
-
path that trains, a comparison that says what it can claim. A ninth pass
|
|
287
|
-
read the first industry run and the scorecard that measured it, and found
|
|
288
|
-
the card measuring self-consistency rather than fitness; 0.1.27 gave it
|
|
289
|
-
fitness rows -- the generalisation gap, an external exam a memoriser cannot
|
|
290
|
-
pass, the engagement's own error-rate bar -- and gave the routed decision
|
|
291
|
-
an abstain path and a reason on every answer.
|
|
292
|
-
[fde-demo-banking](https://github.com/atulkapoor/fde-demo-banking) —
|
|
293
|
-
an industry use case: support intent routing for a retail bank over
|
|
294
|
-
13,083 real messages and seventy-seven queues (Banking77). The framework's
|
|
295
|
-
own reading of a seventy-seven-way decision, its brief parser, its label
|
|
296
|
-
rule and one governance template each failed on it and were fixed before
|
|
297
|
-
a number was quoted; the finished deliverable is an assist-mode router
|
|
298
|
-
that abstains and says why, at 90.2% on what it routes with 18% handed to
|
|
299
|
-
a person, scored on a 3,036-case holdout and the vendor's own test split,
|
|
300
|
-
with `fde scorecard` saying which rows measure fitness and which measure
|
|
301
|
-
self-consistency.
|
|
258
|
+
|
|
259
|
+
- [fde-demo-receipts](https://github.com/atulkapoor/fde-demo-receipts) --
|
|
260
|
+
626 scanned receipts: the holdout refused an overfit implementation, and
|
|
261
|
+
a measured plateau flipped the design from rules to a model, reason on
|
|
262
|
+
the record.
|
|
263
|
+
- [fde-demo-complaints](https://github.com/atulkapoor/fde-demo-complaints) --
|
|
264
|
+
2,034 real consumer complaints through the decision shape: the exam
|
|
265
|
+
refused ambiguous ground truth before it existed, and the loop finished
|
|
266
|
+
**green with the holdout passing**, the framework's first.
|
|
267
|
+
- [fde-demo-rfc-qa](https://github.com/atulkapoor/fde-demo-rfc-qa) --
|
|
268
|
+
freeform QA over 58 real RFCs: 100% recall@10 on real queries, then the
|
|
269
|
+
calibration gate **refusing its own judge** exactly as the prediction
|
|
270
|
+
published beforehand said it would (73.7% agreement, refused; the
|
|
271
|
+
judge's 89.5% was 26 points of flattery over the hand-graded 63.2%).
|
|
272
|
+
- [fde-demo-banking](https://github.com/atulkapoor/fde-demo-banking) --
|
|
273
|
+
an industry use case: support intent routing for a retail bank over
|
|
274
|
+
13,083 real messages and seventy-seven queues. The finished deliverable
|
|
275
|
+
is an assist-mode router that abstains and says why, at 90.2% on what
|
|
276
|
+
it routes with 18% handed to a person, scored on a 3,036-case holdout
|
|
277
|
+
and the vendor's own test split.
|
|
278
|
+
|
|
279
|
+
Fourteen outside readings have shaped the releases since, each finding
|
|
280
|
+
pinned as a check before it was fixed; the story, pass by pass, is in
|
|
281
|
+
[`HISTORY.md`](https://github.com/atulkapoor/fde-framework/blob/main/HISTORY.md).
|
|
302
282
|
|
|
303
283
|
**Built**: the pipeline exists end to end — intake (prose, documents, sample
|
|
304
284
|
pairs, role-scoped interview, hardware scan) → fact log with provenance →
|
|
@@ -344,6 +324,13 @@ drill).
|
|
|
344
324
|
| rfc-qa | prototype | 16/23 | 30.0% on 10 | 30.0% | -- |
|
|
345
325
|
| banking | production (a laptop, attested as such; stopped once by its own stop condition, cleared at the shipped 1.0-nat margin) | 23/25; does not beat the bank's baseline, on coverage | 73.8% on 3,036, abstaining 18.2% | 90.2% | 71.6% on 3,079 |
|
|
346
326
|
|
|
327
|
+
*Stage* is the record's lifecycle stage, computed from its evidence by
|
|
328
|
+
`fde stage`. `production` means the build was deployed and attested by
|
|
329
|
+
name and the field has been journalled through it -- here on a laptop, as
|
|
330
|
+
the record says -- not that production reliability is proven; the claim
|
|
331
|
+
ladder above keeps that unverified until a client's production says
|
|
332
|
+
otherwise.
|
|
333
|
+
|
|
347
334
|
## Two rules
|
|
348
335
|
|
|
349
336
|
Every intake surface — prose, interviews, scans, sample pairs, the client's
|
|
@@ -481,31 +468,12 @@ project/
|
|
|
481
468
|
|
|
482
469
|
Emitted quality is a pinned property, not a promise: the framework's own
|
|
483
470
|
test suite emits projects across representative architecture shapes and
|
|
484
|
-
holds every emission to the operational contract
|
|
485
|
-
variable the code reads
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
milliseconds, the journal stays one JSON line per event under threads, an
|
|
491
|
-
error closes its connection, a bad corpus file is skipped and counted, the
|
|
492
|
-
boundary refuses an endpoint outside it, the ledger survives a restart and
|
|
493
|
-
a torn line, a stopword cannot cite a document and a one-document corpus
|
|
494
|
-
still answers, compaction cannot drop a live key, every eval entry point
|
|
495
|
-
honours the boundary, an oversized corpus refuses the boot with one line,
|
|
496
|
-
readiness degrades rather than denies on a stray file, and the service
|
|
497
|
-
carries a request id on every answer, a truncated query is never a silent
|
|
498
|
-
miss, two processes cannot both reserve one key, a decision read off
|
|
499
|
-
labelled text ships a fitted classifier that refuses to serve a constant,
|
|
500
|
-
refuses an exam that changed since the build, beats the majority on the
|
|
501
|
-
holdout and says which of its scores are in-sample, the exam's probes and
|
|
502
|
-
edges come from cases the baseline was not fitted on and each steering
|
|
503
|
-
probe says what it steers toward, an uncalibrated judge is red until asked
|
|
504
|
-
for by name, a fact learned from a person is marked asserted rather than
|
|
505
|
-
established, and a fine-tuning decision ships a recipe that trains on the
|
|
506
|
-
prompt it serves -- and the deliverable ships its own edge tests, which
|
|
507
|
-
its CI runs. Eight independent audit passes took it from "every request
|
|
508
|
-
500s" to a sign-off with conditions on the decision shape. A quality finding lands there as a check before
|
|
471
|
+
holds every emission to the operational contract, from every environment
|
|
472
|
+
variable the code reads being documented to a classifier that refuses to
|
|
473
|
+
serve a constant; the full list of what is held, and the audit passes that
|
|
474
|
+
put each check there, is in
|
|
475
|
+
[`HISTORY.md`](https://github.com/atulkapoor/fde-framework/blob/main/HISTORY.md).
|
|
476
|
+
A quality finding lands there as a check before
|
|
509
477
|
it lands anywhere as a fix ([`tests/test_acceptance.py`](tests/test_acceptance.py),
|
|
510
478
|
[`tests/test_finetune.py`](tests/test_finetune.py)). And the claim is
|
|
511
479
|
measurable per build: `fde scorecard <project> --holdout <file> --external
|
|
@@ -538,9 +506,10 @@ declared by the tool.
|
|
|
538
506
|
the holdout row, hours and money from the recorded baseline, build and run
|
|
539
507
|
costs from the caller, payback, and a Wilson interval on the accuracy.
|
|
540
508
|
Every line says what it rests on, so the number is argued row by row.
|
|
541
|
-
- **`fde deployed`** and **`fde outcome`** are attestations: where it runs
|
|
542
|
-
who put it there
|
|
543
|
-
|
|
509
|
+
- **`fde deployed`** and **`fde outcome`** are attestations: where it runs,
|
|
510
|
+
who put it there and which build it is (`--project`, which every command
|
|
511
|
+
that reads a project by default then reads); adoption, time to first
|
|
512
|
+
value, whatever the client measured. **`fde outcomes`** prints what the record shows without anyone's
|
|
544
513
|
opinion -- transitions, days to pilot, loop rounds, reversals, incidents.
|
|
545
514
|
- **`fde stakeholders`** maps the engagement's people as the record shows
|
|
546
515
|
them: which of the five roles has been heard (every session carries the
|
|
@@ -587,11 +556,16 @@ declared by the tool.
|
|
|
587
556
|
- **`fde implement --sandbox docker`** runs the coding agent in a container
|
|
588
557
|
closed by construction: only the project mounted, root read-only with a
|
|
589
558
|
scratch `/tmp`, every capability dropped and none gainable, your own user
|
|
590
|
-
rather than root, bounded memory, CPU and processes, the environment
|
|
591
|
-
allowlist
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
559
|
+
rather than root, bounded memory, CPU and processes, the environment a
|
|
560
|
+
default allowlist, and no network unless someone with a name and a
|
|
561
|
+
reason opened it at the terminal (`--allow-network "who: why"`,
|
|
562
|
+
`--env-allow NAME`). The emitted `ops/agent-policy.yaml` sits inside
|
|
563
|
+
the directory the agent writes to, so it can only narrow: it names the
|
|
564
|
+
image and bounded limits, and anything wider it asks for is a request
|
|
565
|
+
the log shows ungranted. The file is part of the fence -- an agent that
|
|
566
|
+
rewrites it, or plants one, has the change reverted and the round says
|
|
567
|
+
so. The implementation log records the image digest the agent actually
|
|
568
|
+
ran on; without the sandbox it says the agent had the host.
|
|
595
569
|
- **`fde experiment`** runs the protocol in
|
|
596
570
|
[`EXPERIMENT.md`](https://github.com/atulkapoor/fde-framework/blob/main/EXPERIMENT.md)
|
|
597
571
|
on the record: `start` assigns the arm by a seeded draw balanced within
|
|
@@ -656,7 +630,7 @@ fde implement project # drive a coding agent until it's green
|
|
|
656
630
|
fde scorecard project --holdout engagements/acme/artifacts/holdout.jsonl # measure it
|
|
657
631
|
|
|
658
632
|
fde stage acme --project project # where it stands, computed off the record
|
|
659
|
-
fde deployed acme --note "runs in the client VPC; platform team put it there"
|
|
633
|
+
fde deployed acme --note "runs in the client VPC; platform team put it there" --project project
|
|
660
634
|
fde drift acme --journal service.log --project project # the field against the exam
|
|
661
635
|
fde incident acme close inc-001 --note "holdout re-scored; pairs redrawn"
|
|
662
636
|
fde outcome acme --metric adoption=0.62 --note "support lead's dashboard, week 3"
|
|
@@ -711,12 +685,13 @@ the same receipts the emitted `ARCHITECTURE.md` prints.
|
|
|
711
685
|
| `fde reuse <eng> <stack>` | record what the client already operates, so reuse can beat adoption |
|
|
712
686
|
| `fde locale <eng> eu-gdpr` | jurisdiction pack: presets plus obligations emitted as COMPLIANCE.md |
|
|
713
687
|
| `fde architect <eng>` | the design, rationale and rejections |
|
|
688
|
+
| `fde report <eng> [--out brief.md]` | the decision brief: the problem as stated, the stage, what is known and who said it, the outcome contract, the design with its reasons and rejections, what it rests on, the debt, the stop conditions, the next decision -- one Markdown file, before any build |
|
|
714
689
|
| `fde build <eng> --out project` | emit; refuses while gates block |
|
|
715
690
|
| `fde implement project/` | drive a coding agent until the emitted evals pass, inside guardrails |
|
|
716
691
|
| `fde scorecard project/ --holdout <file>` | measure production grade: every property the deliverable can prove, with the number, in `SCORECARD.md` |
|
|
717
692
|
| `fde scorecard project/ --holdout <file> --coverage-floor 0.97 --max-gap 0.08` | the engagement's own bars: the share the system must answer for the baseline row to hold (default: 1 minus the baseline's exception rate), and its limit on the golden-to-holdout gap (protocol default 20%) |
|
|
718
693
|
| `fde stage <eng>` | where the engagement stands, computed from the record; transitions appended to `lifecycle.jsonl` (`--no-record` to look without appending) |
|
|
719
|
-
| `fde deployed <eng> --note "..."` | attest the deployment: where it runs
|
|
694
|
+
| `fde deployed <eng> --note "..." [--project <dir>]` | attest the deployment: where it runs, who put it there, which build |
|
|
720
695
|
| `fde drift <eng> --journal <log>` | the field against the exam: abstention, mix, errors, margins; opens an incident and exits 1 when it moved |
|
|
721
696
|
| `fde incident <eng> list \| close <id> --note "..."` | incidents on the record; an open one holds the stage at pilot |
|
|
722
697
|
| `fde outcome <eng> --metric adoption=0.62` / `fde outcomes <eng>` | outcomes measured in the field; what the record shows without opinion |
|
|
@@ -45,6 +45,7 @@ pip install fde-framework
|
|
|
45
45
|
fde start acme --statement "Extract fields from supplier invoices."
|
|
46
46
|
fde ask acme --role admin # role-scoped discovery interview
|
|
47
47
|
fde architect acme # topology + chosen approaches (rationale lands in ARCHITECTURE.md)
|
|
48
|
+
fde report acme # the decision brief, for whoever has to act on it and is not here
|
|
48
49
|
fde build acme --out project # refuses: eight gates guard the build
|
|
49
50
|
# ...verify data access, capture the baseline, name the eval owner (each gate prints its remedy), then:
|
|
50
51
|
fde build acme --out project # code + evals + deploy assets + runbook
|
|
@@ -114,11 +115,13 @@ It serves `triage`, `start`, `frame`, `status`, `next`, `stage`, `debt`,
|
|
|
114
115
|
`stop_when` and `history`, each returning exactly what the terminal prints,
|
|
115
116
|
refusals included, beside a small envelope an agent can branch on without
|
|
116
117
|
parsing prose: `schema_version`, `status` (ok, blocked, refused, failed),
|
|
117
|
-
`mutated`, and the workspace. The
|
|
118
|
-
never a reading of its text
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
`mutated`, and the workspace. The status follows the command's exit,
|
|
119
|
+
never a reading of its text; `mutated` is measured, the record's files
|
|
120
|
+
hashed before and after, so a write that failed partway and left changes
|
|
121
|
+
says so. Its contract is a JSON Schema, `fde mcp --schema`, that every
|
|
122
|
+
reply is tested against; a client pins `schema_version`, which moves
|
|
123
|
+
only when a field changes meaning or goes away, never when one is added
|
|
124
|
+
(it moved to 2 when `mutated` became a measurement). An engagement is named as `start` named
|
|
122
125
|
it (`start(name="acme")`, then `status(engagement="acme")`), or by its
|
|
123
126
|
path. An agent is not a person, so every path it supplies must stay
|
|
124
127
|
inside one workspace, the directory the server started in or
|
|
@@ -197,7 +200,7 @@ ladder, so nothing here can be over-read:
|
|
|
197
200
|
|
|
198
201
|
| Claim | Status | The evidence, and where it stops |
|
|
199
202
|
|---|---|---|
|
|
200
|
-
| The framework is implemented | verified | 1,
|
|
203
|
+
| The framework is implemented | verified | 1,328 tests on three Pythons in CI; lint clean; every audit finding pinned as a check before it was fixed; every release installed from the published wheel into a fresh interpreter and walked through the first five minutes |
|
|
201
204
|
| A build is reproducible | verified | byte-identical rebuild pinned by test; each public demo carries a Reproduce section and its digests |
|
|
202
205
|
| The decisions generalise | partial | four shapes (extraction, freeform QA, a labelled decision, seventy-seven-way routing) on real data; one industry set; `fde kb sweep` names the shapes nothing serves |
|
|
203
206
|
| The deliverable is production-reliable | unverified | no production engagement; the banking operating loop ran on a laptop and its record says so |
|
|
@@ -207,54 +210,30 @@ ladder, so nothing here can be over-read:
|
|
|
207
210
|
|
|
208
211
|
**Demonstrated**: four complete engagements have run end to end on real
|
|
209
212
|
data, all public with every refusal preserved.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
[fde-demo-complaints](https://github.com/atulkapoor/fde-demo-complaints)
|
|
216
|
-
2,034 real consumer complaints through the decision shape: the exam
|
|
217
|
-
refused ambiguous ground truth before it existed, the
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
stopping short -- a mis-specified baseline, an in-sample exam, a training
|
|
235
|
-
recipe that trained unshuffled on a prompt it never served -- and 0.1.23
|
|
236
|
-
answered again the same way. 0.1.24 then ran the fine-tuning recipe for
|
|
237
|
-
real on a small base model: the adapter learned the house style on cases
|
|
238
|
-
it never saw, and the six defects that run exposed in the harness, the
|
|
239
|
-
serving path and the comparison are fixed and pinned. An eighth pass gave
|
|
240
|
-
the decision shape its first sign-off, with conditions, and 0.1.25 met
|
|
241
|
-
them: probes on typical cases, label phrases rather than words, a merge
|
|
242
|
-
path that trains, a comparison that says what it can claim. A ninth pass
|
|
243
|
-
read the first industry run and the scorecard that measured it, and found
|
|
244
|
-
the card measuring self-consistency rather than fitness; 0.1.27 gave it
|
|
245
|
-
fitness rows -- the generalisation gap, an external exam a memoriser cannot
|
|
246
|
-
pass, the engagement's own error-rate bar -- and gave the routed decision
|
|
247
|
-
an abstain path and a reason on every answer.
|
|
248
|
-
[fde-demo-banking](https://github.com/atulkapoor/fde-demo-banking) —
|
|
249
|
-
an industry use case: support intent routing for a retail bank over
|
|
250
|
-
13,083 real messages and seventy-seven queues (Banking77). The framework's
|
|
251
|
-
own reading of a seventy-seven-way decision, its brief parser, its label
|
|
252
|
-
rule and one governance template each failed on it and were fixed before
|
|
253
|
-
a number was quoted; the finished deliverable is an assist-mode router
|
|
254
|
-
that abstains and says why, at 90.2% on what it routes with 18% handed to
|
|
255
|
-
a person, scored on a 3,036-case holdout and the vendor's own test split,
|
|
256
|
-
with `fde scorecard` saying which rows measure fitness and which measure
|
|
257
|
-
self-consistency.
|
|
213
|
+
|
|
214
|
+
- [fde-demo-receipts](https://github.com/atulkapoor/fde-demo-receipts) --
|
|
215
|
+
626 scanned receipts: the holdout refused an overfit implementation, and
|
|
216
|
+
a measured plateau flipped the design from rules to a model, reason on
|
|
217
|
+
the record.
|
|
218
|
+
- [fde-demo-complaints](https://github.com/atulkapoor/fde-demo-complaints) --
|
|
219
|
+
2,034 real consumer complaints through the decision shape: the exam
|
|
220
|
+
refused ambiguous ground truth before it existed, and the loop finished
|
|
221
|
+
**green with the holdout passing**, the framework's first.
|
|
222
|
+
- [fde-demo-rfc-qa](https://github.com/atulkapoor/fde-demo-rfc-qa) --
|
|
223
|
+
freeform QA over 58 real RFCs: 100% recall@10 on real queries, then the
|
|
224
|
+
calibration gate **refusing its own judge** exactly as the prediction
|
|
225
|
+
published beforehand said it would (73.7% agreement, refused; the
|
|
226
|
+
judge's 89.5% was 26 points of flattery over the hand-graded 63.2%).
|
|
227
|
+
- [fde-demo-banking](https://github.com/atulkapoor/fde-demo-banking) --
|
|
228
|
+
an industry use case: support intent routing for a retail bank over
|
|
229
|
+
13,083 real messages and seventy-seven queues. The finished deliverable
|
|
230
|
+
is an assist-mode router that abstains and says why, at 90.2% on what
|
|
231
|
+
it routes with 18% handed to a person, scored on a 3,036-case holdout
|
|
232
|
+
and the vendor's own test split.
|
|
233
|
+
|
|
234
|
+
Fourteen outside readings have shaped the releases since, each finding
|
|
235
|
+
pinned as a check before it was fixed; the story, pass by pass, is in
|
|
236
|
+
[`HISTORY.md`](https://github.com/atulkapoor/fde-framework/blob/main/HISTORY.md).
|
|
258
237
|
|
|
259
238
|
**Built**: the pipeline exists end to end — intake (prose, documents, sample
|
|
260
239
|
pairs, role-scoped interview, hardware scan) → fact log with provenance →
|
|
@@ -300,6 +279,13 @@ drill).
|
|
|
300
279
|
| rfc-qa | prototype | 16/23 | 30.0% on 10 | 30.0% | -- |
|
|
301
280
|
| banking | production (a laptop, attested as such; stopped once by its own stop condition, cleared at the shipped 1.0-nat margin) | 23/25; does not beat the bank's baseline, on coverage | 73.8% on 3,036, abstaining 18.2% | 90.2% | 71.6% on 3,079 |
|
|
302
281
|
|
|
282
|
+
*Stage* is the record's lifecycle stage, computed from its evidence by
|
|
283
|
+
`fde stage`. `production` means the build was deployed and attested by
|
|
284
|
+
name and the field has been journalled through it -- here on a laptop, as
|
|
285
|
+
the record says -- not that production reliability is proven; the claim
|
|
286
|
+
ladder above keeps that unverified until a client's production says
|
|
287
|
+
otherwise.
|
|
288
|
+
|
|
303
289
|
## Two rules
|
|
304
290
|
|
|
305
291
|
Every intake surface — prose, interviews, scans, sample pairs, the client's
|
|
@@ -437,31 +423,12 @@ project/
|
|
|
437
423
|
|
|
438
424
|
Emitted quality is a pinned property, not a promise: the framework's own
|
|
439
425
|
test suite emits projects across representative architecture shapes and
|
|
440
|
-
holds every emission to the operational contract
|
|
441
|
-
variable the code reads
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
milliseconds, the journal stays one JSON line per event under threads, an
|
|
447
|
-
error closes its connection, a bad corpus file is skipped and counted, the
|
|
448
|
-
boundary refuses an endpoint outside it, the ledger survives a restart and
|
|
449
|
-
a torn line, a stopword cannot cite a document and a one-document corpus
|
|
450
|
-
still answers, compaction cannot drop a live key, every eval entry point
|
|
451
|
-
honours the boundary, an oversized corpus refuses the boot with one line,
|
|
452
|
-
readiness degrades rather than denies on a stray file, and the service
|
|
453
|
-
carries a request id on every answer, a truncated query is never a silent
|
|
454
|
-
miss, two processes cannot both reserve one key, a decision read off
|
|
455
|
-
labelled text ships a fitted classifier that refuses to serve a constant,
|
|
456
|
-
refuses an exam that changed since the build, beats the majority on the
|
|
457
|
-
holdout and says which of its scores are in-sample, the exam's probes and
|
|
458
|
-
edges come from cases the baseline was not fitted on and each steering
|
|
459
|
-
probe says what it steers toward, an uncalibrated judge is red until asked
|
|
460
|
-
for by name, a fact learned from a person is marked asserted rather than
|
|
461
|
-
established, and a fine-tuning decision ships a recipe that trains on the
|
|
462
|
-
prompt it serves -- and the deliverable ships its own edge tests, which
|
|
463
|
-
its CI runs. Eight independent audit passes took it from "every request
|
|
464
|
-
500s" to a sign-off with conditions on the decision shape. A quality finding lands there as a check before
|
|
426
|
+
holds every emission to the operational contract, from every environment
|
|
427
|
+
variable the code reads being documented to a classifier that refuses to
|
|
428
|
+
serve a constant; the full list of what is held, and the audit passes that
|
|
429
|
+
put each check there, is in
|
|
430
|
+
[`HISTORY.md`](https://github.com/atulkapoor/fde-framework/blob/main/HISTORY.md).
|
|
431
|
+
A quality finding lands there as a check before
|
|
465
432
|
it lands anywhere as a fix ([`tests/test_acceptance.py`](tests/test_acceptance.py),
|
|
466
433
|
[`tests/test_finetune.py`](tests/test_finetune.py)). And the claim is
|
|
467
434
|
measurable per build: `fde scorecard <project> --holdout <file> --external
|
|
@@ -494,9 +461,10 @@ declared by the tool.
|
|
|
494
461
|
the holdout row, hours and money from the recorded baseline, build and run
|
|
495
462
|
costs from the caller, payback, and a Wilson interval on the accuracy.
|
|
496
463
|
Every line says what it rests on, so the number is argued row by row.
|
|
497
|
-
- **`fde deployed`** and **`fde outcome`** are attestations: where it runs
|
|
498
|
-
who put it there
|
|
499
|
-
|
|
464
|
+
- **`fde deployed`** and **`fde outcome`** are attestations: where it runs,
|
|
465
|
+
who put it there and which build it is (`--project`, which every command
|
|
466
|
+
that reads a project by default then reads); adoption, time to first
|
|
467
|
+
value, whatever the client measured. **`fde outcomes`** prints what the record shows without anyone's
|
|
500
468
|
opinion -- transitions, days to pilot, loop rounds, reversals, incidents.
|
|
501
469
|
- **`fde stakeholders`** maps the engagement's people as the record shows
|
|
502
470
|
them: which of the five roles has been heard (every session carries the
|
|
@@ -543,11 +511,16 @@ declared by the tool.
|
|
|
543
511
|
- **`fde implement --sandbox docker`** runs the coding agent in a container
|
|
544
512
|
closed by construction: only the project mounted, root read-only with a
|
|
545
513
|
scratch `/tmp`, every capability dropped and none gainable, your own user
|
|
546
|
-
rather than root, bounded memory, CPU and processes, the environment
|
|
547
|
-
allowlist
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
514
|
+
rather than root, bounded memory, CPU and processes, the environment a
|
|
515
|
+
default allowlist, and no network unless someone with a name and a
|
|
516
|
+
reason opened it at the terminal (`--allow-network "who: why"`,
|
|
517
|
+
`--env-allow NAME`). The emitted `ops/agent-policy.yaml` sits inside
|
|
518
|
+
the directory the agent writes to, so it can only narrow: it names the
|
|
519
|
+
image and bounded limits, and anything wider it asks for is a request
|
|
520
|
+
the log shows ungranted. The file is part of the fence -- an agent that
|
|
521
|
+
rewrites it, or plants one, has the change reverted and the round says
|
|
522
|
+
so. The implementation log records the image digest the agent actually
|
|
523
|
+
ran on; without the sandbox it says the agent had the host.
|
|
551
524
|
- **`fde experiment`** runs the protocol in
|
|
552
525
|
[`EXPERIMENT.md`](https://github.com/atulkapoor/fde-framework/blob/main/EXPERIMENT.md)
|
|
553
526
|
on the record: `start` assigns the arm by a seeded draw balanced within
|
|
@@ -612,7 +585,7 @@ fde implement project # drive a coding agent until it's green
|
|
|
612
585
|
fde scorecard project --holdout engagements/acme/artifacts/holdout.jsonl # measure it
|
|
613
586
|
|
|
614
587
|
fde stage acme --project project # where it stands, computed off the record
|
|
615
|
-
fde deployed acme --note "runs in the client VPC; platform team put it there"
|
|
588
|
+
fde deployed acme --note "runs in the client VPC; platform team put it there" --project project
|
|
616
589
|
fde drift acme --journal service.log --project project # the field against the exam
|
|
617
590
|
fde incident acme close inc-001 --note "holdout re-scored; pairs redrawn"
|
|
618
591
|
fde outcome acme --metric adoption=0.62 --note "support lead's dashboard, week 3"
|
|
@@ -667,12 +640,13 @@ the same receipts the emitted `ARCHITECTURE.md` prints.
|
|
|
667
640
|
| `fde reuse <eng> <stack>` | record what the client already operates, so reuse can beat adoption |
|
|
668
641
|
| `fde locale <eng> eu-gdpr` | jurisdiction pack: presets plus obligations emitted as COMPLIANCE.md |
|
|
669
642
|
| `fde architect <eng>` | the design, rationale and rejections |
|
|
643
|
+
| `fde report <eng> [--out brief.md]` | the decision brief: the problem as stated, the stage, what is known and who said it, the outcome contract, the design with its reasons and rejections, what it rests on, the debt, the stop conditions, the next decision -- one Markdown file, before any build |
|
|
670
644
|
| `fde build <eng> --out project` | emit; refuses while gates block |
|
|
671
645
|
| `fde implement project/` | drive a coding agent until the emitted evals pass, inside guardrails |
|
|
672
646
|
| `fde scorecard project/ --holdout <file>` | measure production grade: every property the deliverable can prove, with the number, in `SCORECARD.md` |
|
|
673
647
|
| `fde scorecard project/ --holdout <file> --coverage-floor 0.97 --max-gap 0.08` | the engagement's own bars: the share the system must answer for the baseline row to hold (default: 1 minus the baseline's exception rate), and its limit on the golden-to-holdout gap (protocol default 20%) |
|
|
674
648
|
| `fde stage <eng>` | where the engagement stands, computed from the record; transitions appended to `lifecycle.jsonl` (`--no-record` to look without appending) |
|
|
675
|
-
| `fde deployed <eng> --note "..."` | attest the deployment: where it runs
|
|
649
|
+
| `fde deployed <eng> --note "..." [--project <dir>]` | attest the deployment: where it runs, who put it there, which build |
|
|
676
650
|
| `fde drift <eng> --journal <log>` | the field against the exam: abstention, mix, errors, margins; opens an incident and exits 1 when it moved |
|
|
677
651
|
| `fde incident <eng> list \| close <id> --note "..."` | incidents on the record; an open one holds the stage at pilot |
|
|
678
652
|
| `fde outcome <eng> --metric adoption=0.62` / `fde outcomes <eng>` | outcomes measured in the field; what the record shows without opinion |
|
|
@@ -60,6 +60,12 @@ fde build engagements/acme --out project
|
|
|
60
60
|
# wrote project
|
|
61
61
|
# evals: 2 golden, 0 edge, 8 adversarial
|
|
62
62
|
# next: fde implement project --holdout engagements/acme/artifacts/holdout.jsonl
|
|
63
|
+
#
|
|
64
|
+
# The pairs are text, and the design's first stage is OCR. Text enters after
|
|
65
|
+
# it: `python -m evals.harness` reaches the extraction stage (and fails there
|
|
66
|
+
# until fde implement), and says the OCR stage went unexercised -- bring
|
|
67
|
+
# page-shaped pairs to test the reading. A build whose golden cases cannot
|
|
68
|
+
# enter its own pipeline is refused before it is written.
|
|
63
69
|
```
|
|
64
70
|
|
|
65
71
|
The emitted `project/` holds `app/` (pipeline in topological order, boundary
|