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.
Files changed (407) hide show
  1. {fde_framework-0.1.45 → fde_framework-0.1.47}/CHANGELOG.md +101 -0
  2. {fde_framework-0.1.45 → fde_framework-0.1.47}/PKG-INFO +65 -90
  3. {fde_framework-0.1.45 → fde_framework-0.1.47}/README.md +63 -89
  4. {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/invoice-extraction/README.md +6 -0
  5. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/ocr-pipeline.plain.py.j2 +17 -0
  6. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/ocr-pipeline.tesseract.py.j2 +12 -0
  7. {fde_framework-0.1.45 → fde_framework-0.1.47}/pyproject.toml +2 -2
  8. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/cli.py +76 -23
  9. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/emit.py +127 -9
  10. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/factlog.py +15 -3
  11. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/implement.py +14 -2
  12. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/mcp_server.py +31 -9
  13. fde_framework-0.1.47/src/fde/report.py +203 -0
  14. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/sandbox.py +85 -19
  15. fde_framework-0.1.47/tests/test_assets.py +37 -0
  16. fde_framework-0.1.47/tests/test_build_receipt.py +205 -0
  17. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_implement.py +32 -0
  18. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_mcp.py +32 -0
  19. fde_framework-0.1.47/tests/test_report.py +80 -0
  20. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_sandbox.py +32 -10
  21. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_sanitisation.py +24 -3
  22. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stop.py +30 -0
  23. fde_framework-0.1.45/tests/test_build_receipt.py +0 -105
  24. {fde_framework-0.1.45 → fde_framework-0.1.47}/.gitignore +0 -0
  25. {fde_framework-0.1.45 → fde_framework-0.1.47}/LICENSE +0 -0
  26. {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/policy-qa/README.md +0 -0
  27. {fde_framework-0.1.45 → fde_framework-0.1.47}/examples/support-triage/README.md +0 -0
  28. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/ansible-playbook.md +0 -0
  29. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/assisted-deterministic.md +0 -0
  30. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/audit-only.md +0 -0
  31. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/boundary-and-audit.md +0 -0
  32. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/cascade.md +0 -0
  33. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/classical-ml.md +0 -0
  34. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/compose.md +0 -0
  35. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/decision-log.md +0 -0
  36. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/deterministic-masking.md +0 -0
  37. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/deterministic.md +0 -0
  38. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/direct-call.md +0 -0
  39. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/episodic-store.md +0 -0
  40. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/explainability-record.md +0 -0
  41. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/field-match.md +0 -0
  42. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/finetune.md +0 -0
  43. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/fixed-sequence.md +0 -0
  44. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/gitops.md +0 -0
  45. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/governed-tools.md +0 -0
  46. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/graph-expanded-retrieval.md +0 -0
  47. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/graph-retrieval.md +0 -0
  48. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/hybrid-search.md +0 -0
  49. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/judged.md +0 -0
  50. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/keyword-search.md +0 -0
  51. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/kubernetes-manifests.md +0 -0
  52. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/labelled-decision.md +0 -0
  53. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/labelled-metrics.md +0 -0
  54. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm-extraction.md +0 -0
  55. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm-scrubbing.md +0 -0
  56. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/llm.md +0 -0
  57. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/local-embedding.md +0 -0
  58. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/managed-api.md +0 -0
  59. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/managed-embedding.md +0 -0
  60. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/manual-runbook.md +0 -0
  61. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/model-planner.md +0 -0
  62. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/ocr-pipeline.md +0 -0
  63. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/optimisation-reasoning.md +0 -0
  64. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/optimisation.md +0 -0
  65. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/passthrough.md +0 -0
  66. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/reranked-retrieval.md +0 -0
  67. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/role-scoped-authority.md +0 -0
  68. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/segmentation.md +0 -0
  69. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/self-hosted.md +0 -0
  70. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/serverless-gpu.md +0 -0
  71. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/speech-transcription.md +0 -0
  72. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/structured-logs.md +0 -0
  73. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/systemd-unit.md +0 -0
  74. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/terraform-module.md +0 -0
  75. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/text-extraction.md +0 -0
  76. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/traced.md +0 -0
  77. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/vector-search.md +0 -0
  78. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/video-ingestion.md +0 -0
  79. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/windowed-ingestion.md +0 -0
  80. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/approaches/working-state.md +0 -0
  81. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/churn-scoring.md +0 -0
  82. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/route-planning.md +0 -0
  83. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/structured-extraction.md +0 -0
  84. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/cases/studio-style.md +0 -0
  85. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/accountability.md +0 -0
  86. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/deployment.md +0 -0
  87. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/embedding.md +0 -0
  88. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/evaluation.md +0 -0
  89. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/governance.md +0 -0
  90. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/integration.md +0 -0
  91. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/memory.md +0 -0
  92. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/observability.md +0 -0
  93. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/perception.md +0 -0
  94. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/planning.md +0 -0
  95. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/provisioning.md +0 -0
  96. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/reasoning.md +0 -0
  97. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/redaction.md +0 -0
  98. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/representation.md +0 -0
  99. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/retrieval.md +0 -0
  100. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/components/serving.md +0 -0
  101. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/accelerator.md +0 -0
  102. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/access_model.md +0 -0
  103. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/arrival_rate.md +0 -0
  104. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/availability_target.md +0 -0
  105. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/cheap_path_coverage.md +0 -0
  106. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/confidence_calibrated.md +0 -0
  107. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/container_competence.md +0 -0
  108. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/corpus_churn.md +0 -0
  109. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/corpus_size.md +0 -0
  110. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/data_residency.md +0 -0
  111. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/environment_lifetime.md +0 -0
  112. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/existing_cluster.md +0 -0
  113. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/existing_iac_tool.md +0 -0
  114. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/external_systems.md +0 -0
  115. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/hosting.md +0 -0
  116. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/human_waiting.md +0 -0
  117. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/input_format.md +0 -0
  118. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/interpretability_required.md +0 -0
  119. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/labelled_count.md +0 -0
  120. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/latency_budget_ms.md +0 -0
  121. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/licence_posture.md +0 -0
  122. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/operates_after_handover.md +0 -0
  123. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/output_shape.md +0 -0
  124. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/provisioning_api.md +0 -0
  125. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/query_pattern.md +0 -0
  126. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/recall_span.md +0 -0
  127. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/dimensions/sensitivity_present.md +0 -0
  128. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Generator.md +0 -0
  129. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Guard.md +0 -0
  130. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Mapper.md +0 -0
  131. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/ModelServer.md +0 -0
  132. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Parser.md +0 -0
  133. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Planner.md +0 -0
  134. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Retriever.md +0 -0
  135. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Scorer.md +0 -0
  136. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Store.md +0 -0
  137. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/ToolBoundary.md +0 -0
  138. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/interfaces/Tracer.md +0 -0
  139. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/locales/eu-gdpr.md +0 -0
  140. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/locales/in-dpdp.md +0 -0
  141. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/ansible-playbook.md +0 -0
  142. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/assisted-deterministic.md +0 -0
  143. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/audit-only.md +0 -0
  144. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/boundary-and-audit.md +0 -0
  145. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-reasoning.md +0 -0
  146. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-representation.md +0 -0
  147. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/cascade-retrieval.md +0 -0
  148. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/classical-ml-reasoning.md +0 -0
  149. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/classical-ml.md +0 -0
  150. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/compose.md +0 -0
  151. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/decision-log.md +0 -0
  152. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/deterministic-masking.md +0 -0
  153. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/deterministic.md +0 -0
  154. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/direct-call.md +0 -0
  155. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/episodic-store.md +0 -0
  156. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/explainability-record.md +0 -0
  157. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/field-match.md +0 -0
  158. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/finetune-representation.md +0 -0
  159. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/finetune.md +0 -0
  160. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/fixed-sequence.md +0 -0
  161. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/gitops.md +0 -0
  162. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/governed-tools.md +0 -0
  163. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/graph-expanded-retrieval.md +0 -0
  164. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/graph-retrieval.md +0 -0
  165. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/hybrid-search.md +0 -0
  166. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/judged.md +0 -0
  167. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/keyword-search.md +0 -0
  168. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/kubernetes-manifests.md +0 -0
  169. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/labelled-decision.md +0 -0
  170. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/labelled-metrics.md +0 -0
  171. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm-representation.md +0 -0
  172. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm-scrubbing.md +0 -0
  173. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/llm.md +0 -0
  174. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/local-embedding.md +0 -0
  175. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/managed-api.md +0 -0
  176. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/managed-embedding.md +0 -0
  177. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/manual-runbook.md +0 -0
  178. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/model-planner.md +0 -0
  179. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/ocr-pipeline.md +0 -0
  180. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/optimisation-reasoning.md +0 -0
  181. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/optimisation.md +0 -0
  182. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/passthrough.md +0 -0
  183. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/reranked-retrieval.md +0 -0
  184. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/role-scoped-authority.md +0 -0
  185. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/segmentation.md +0 -0
  186. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/self-hosted.md +0 -0
  187. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/serverless-gpu.md +0 -0
  188. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/speech-transcription.md +0 -0
  189. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/structured-logs.md +0 -0
  190. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/systemd-unit.md +0 -0
  191. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/terraform-module.md +0 -0
  192. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/text-extraction.md +0 -0
  193. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/traced.md +0 -0
  194. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/vector-search.md +0 -0
  195. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/video-ingestion.md +0 -0
  196. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/windowed-ingestion.md +0 -0
  197. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/patterns/working-state.md +0 -0
  198. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/langgraph.md +0 -0
  199. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/llamaindex.md +0 -0
  200. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/local-judge.md +0 -0
  201. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/mcp.md +0 -0
  202. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/ollama.md +0 -0
  203. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/openai-judge.md +0 -0
  204. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/opentelemetry.md +0 -0
  205. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/ortools.md +0 -0
  206. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/peft.md +0 -0
  207. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/pgvector.md +0 -0
  208. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/plain-python.md +0 -0
  209. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/qdrant.md +0 -0
  210. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/supermemory.md +0 -0
  211. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/tesseract.md +0 -0
  212. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/vllm.md +0 -0
  213. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/whisper.md +0 -0
  214. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/stacks/xgboost.md +0 -0
  215. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/accountability/decision-log.plain.py.j2 +0 -0
  216. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/accountability/explainability-record.plain.py.j2 +0 -0
  217. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/compose.plain.py.j2 +0 -0
  218. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/kubernetes-manifests.plain.py.j2 +0 -0
  219. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/deployment/systemd-unit.plain.py.j2 +0 -0
  220. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/embedding/local-embedding.plain.py.j2 +0 -0
  221. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/embedding/managed-embedding.plain.py.j2 +0 -0
  222. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/field-match.plain.py.j2 +0 -0
  223. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.local-judge.py.j2 +0 -0
  224. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.openai-judge.py.j2 +0 -0
  225. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/judged.plain.py.j2 +0 -0
  226. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/labelled-metrics.plain.py.j2 +0 -0
  227. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/evaluation/labelled-metrics.xgboost.py.j2 +0 -0
  228. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/audit-only.plain.py.j2 +0 -0
  229. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/boundary-and-audit.plain.py.j2 +0 -0
  230. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/governance/role-scoped-authority.plain.py.j2 +0 -0
  231. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/direct-call.plain.py.j2 +0 -0
  232. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/governed-tools.mcp.py.j2 +0 -0
  233. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/integration/governed-tools.plain.py.j2 +0 -0
  234. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.pgvector.py.j2 +0 -0
  235. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.plain.py.j2 +0 -0
  236. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/episodic-store.supermemory.py.j2 +0 -0
  237. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/memory/working-state.plain.py.j2 +0 -0
  238. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/structured-logs.plain.py.j2 +0 -0
  239. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/traced.opentelemetry.py.j2 +0 -0
  240. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/observability/traced.plain.py.j2 +0 -0
  241. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/passthrough.plain.py.j2 +0 -0
  242. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/speech-transcription.plain.py.j2 +0 -0
  243. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/speech-transcription.whisper.py.j2 +0 -0
  244. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/text-extraction.plain.py.j2 +0 -0
  245. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/video-ingestion.plain.py.j2 +0 -0
  246. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/perception/windowed-ingestion.plain.py.j2 +0 -0
  247. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/fixed-sequence.plain.py.j2 +0 -0
  248. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/model-planner.langgraph.py.j2 +0 -0
  249. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/model-planner.plain.py.j2 +0 -0
  250. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/optimisation.ortools.py.j2 +0 -0
  251. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/planning/optimisation.plain.py.j2 +0 -0
  252. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/ansible-playbook.plain.py.j2 +0 -0
  253. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/gitops.plain.py.j2 +0 -0
  254. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/manual-runbook.plain.py.j2 +0 -0
  255. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/provisioning/terraform-module.plain.py.j2 +0 -0
  256. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/cascade.plain.py.j2 +0 -0
  257. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/classical-ml.plain.py.j2 +0 -0
  258. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/classical-ml.xgboost.py.j2 +0 -0
  259. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/finetune.plain.py.j2 +0 -0
  260. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/labelled-decision.plain.py.j2 +0 -0
  261. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/llm.plain.py.j2 +0 -0
  262. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/optimisation.ortools.py.j2 +0 -0
  263. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/reasoning/optimisation.plain.py.j2 +0 -0
  264. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/redaction/deterministic-masking.plain.py.j2 +0 -0
  265. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/redaction/llm-scrubbing.plain.py.j2 +0 -0
  266. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/assisted.plain.py.j2 +0 -0
  267. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/cascade.plain.py.j2 +0 -0
  268. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/classical-ml.plain.py.j2 +0 -0
  269. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/classical-ml.xgboost.py.j2 +0 -0
  270. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/deterministic.plain.py.j2 +0 -0
  271. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/finetune.plain.py.j2 +0 -0
  272. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/llm.plain.py.j2 +0 -0
  273. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/representation/segmentation.plain.py.j2 +0 -0
  274. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/cascade.plain.py.j2 +0 -0
  275. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.pgvector.py.j2 +0 -0
  276. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.plain.py.j2 +0 -0
  277. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-expanded-retrieval.qdrant.py.j2 +0 -0
  278. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.pgvector.py.j2 +0 -0
  279. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.plain.py.j2 +0 -0
  280. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/graph-retrieval.qdrant.py.j2 +0 -0
  281. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/hybrid-search.plain.py.j2 +0 -0
  282. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/keyword-search.plain.py.j2 +0 -0
  283. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/reranked-retrieval.plain.py.j2 +0 -0
  284. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.llamaindex.py.j2 +0 -0
  285. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.pgvector.py.j2 +0 -0
  286. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.plain.py.j2 +0 -0
  287. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/retrieval/vector-search.qdrant.py.j2 +0 -0
  288. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/managed-api.plain.py.j2 +0 -0
  289. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.ollama.py.j2 +0 -0
  290. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.plain.py.j2 +0 -0
  291. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/self-hosted.vllm.py.j2 +0 -0
  292. {fde_framework-0.1.45 → fde_framework-0.1.47}/framework/templates/serving/serverless-gpu.plain.py.j2 +0 -0
  293. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/__init__.py +0 -0
  294. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/architect.py +0 -0
  295. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/bench.py +0 -0
  296. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/costing.py +0 -0
  297. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/debt.py +0 -0
  298. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/decide.py +0 -0
  299. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/decompose.py +0 -0
  300. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/deploy.py +0 -0
  301. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/drift.py +0 -0
  302. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/evolution.py +0 -0
  303. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/experiment.py +0 -0
  304. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/forecast.py +0 -0
  305. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/gates.py +0 -0
  306. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/graph.py +0 -0
  307. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/history.py +0 -0
  308. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/impact.py +0 -0
  309. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/importer.py +0 -0
  310. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/__init__.py +0 -0
  311. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/answers.py +0 -0
  312. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/documents.py +0 -0
  313. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/interview.py +0 -0
  314. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/llm_reader.py +0 -0
  315. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/prose.py +0 -0
  316. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/intake/samples.py +0 -0
  317. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/lifecycle.py +0 -0
  318. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/__init__.py +0 -0
  319. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/base.py +0 -0
  320. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/fact.py +0 -0
  321. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/profile.py +0 -0
  322. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/respondent.py +0 -0
  323. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/models/schema.py +0 -0
  324. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/moves.py +0 -0
  325. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/ops.py +0 -0
  326. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/predicate.py +0 -0
  327. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/realization.py +0 -0
  328. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/registry.py +0 -0
  329. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/scan.py +0 -0
  330. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/scorecard.py +0 -0
  331. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/space.py +0 -0
  332. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/stakeholders.py +0 -0
  333. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/stop.py +0 -0
  334. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/training.py +0 -0
  335. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/value.py +0 -0
  336. {fde_framework-0.1.45 → fde_framework-0.1.47}/src/fde/workflow.py +0 -0
  337. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/__init__.py +0 -0
  338. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/conftest.py +0 -0
  339. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/models/__init__.py +0 -0
  340. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/models/test_profile.py +0 -0
  341. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_acceptance.py +0 -0
  342. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_access_and_sensitivity.py +0 -0
  343. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_answers.py +0 -0
  344. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_audit_fixes.py +0 -0
  345. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_bench.py +0 -0
  346. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cascade.py +0 -0
  347. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_engagement.py +0 -0
  348. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_evolution.py +0 -0
  349. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_gates.py +0 -0
  350. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_intake.py +0 -0
  351. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_kb.py +0 -0
  352. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_robustness.py +0 -0
  353. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_cli_samples.py +0 -0
  354. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_costing.py +0 -0
  355. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_coverage.py +0 -0
  356. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_dead_zones.py +0 -0
  357. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_debt.py +0 -0
  358. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_decide.py +0 -0
  359. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_decompose.py +0 -0
  360. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_deploy.py +0 -0
  361. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_documents.py +0 -0
  362. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_drift.py +0 -0
  363. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_embedding.py +0 -0
  364. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_emit.py +0 -0
  365. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_evolution.py +0 -0
  366. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_example_transcript.py +0 -0
  367. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_experiment.py +0 -0
  368. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_factlog.py +0 -0
  369. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_finetune.py +0 -0
  370. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_finetune_real.py +0 -0
  371. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_forecast.py +0 -0
  372. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_gates.py +0 -0
  373. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_history.py +0 -0
  374. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_impact.py +0 -0
  375. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_importer.py +0 -0
  376. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_interview.py +0 -0
  377. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_lifecycle.py +0 -0
  378. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_llm_reader.py +0 -0
  379. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_locales.py +0 -0
  380. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_mcp_stdio.py +0 -0
  381. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_memory_retrieval.py +0 -0
  382. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_more_templates.py +0 -0
  383. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_moves.py +0 -0
  384. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_multimodal.py +0 -0
  385. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_next.py +0 -0
  386. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_ops.py +0 -0
  387. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_outcome_contract.py +0 -0
  388. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_package.py +0 -0
  389. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_prose.py +0 -0
  390. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_realization.py +0 -0
  391. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_registry.py +0 -0
  392. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_release_consistency.py +0 -0
  393. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_remaining.py +0 -0
  394. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_retrieval_eval.py +0 -0
  395. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_reversibility.py +0 -0
  396. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_samples.py +0 -0
  397. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_scan.py +0 -0
  398. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_schema.py +0 -0
  399. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_scorecard.py +0 -0
  400. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_serving.py +0 -0
  401. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_shipped_registry.py +0 -0
  402. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_space.py +0 -0
  403. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stack_swap.py +0 -0
  404. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_stakeholders.py +0 -0
  405. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_supermemory.py +0 -0
  406. {fde_framework-0.1.45 → fde_framework-0.1.47}/tests/test_templates.py +0 -0
  407. {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.45
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 envelope follows the command's exit,
162
- never a reading of its text. Its contract is a JSON Schema, `fde mcp
163
- --schema`, that every reply is tested against; a client pins
164
- `schema_version`, which moves only when a field changes meaning or goes
165
- away, never when one is added. An engagement is named as `start` named
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,316 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 |
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
- [fde-demo-receipts](https://github.com/atulkapoor/fde-demo-receipts) —
255
- 626 scanned receipts through gates, build, and an agent-driven implement
256
- loop (`fde implement`, graded against held-out cases the agent never sees)
257
- whose holdout refused an overfit implementation and whose measured plateau
258
- flipped the design from rules to a model, reason on the record.
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 agent posture was
262
- decided from the facts, and the loop finished **green with the holdout
263
- passing** — the framework's first.
264
- [fde-demo-rfc-qa](https://github.com/atulkapoor/fde-demo-rfc-qa) —
265
- freeform QA over 58 real RFCs: 100% recall@10 on real queries, a green
266
- loop, and then the calibration gate **refusing its own judge** exactly as
267
- the prediction published beforehand said it would (73.7% agreement,
268
- refused; the judge's 89.5% was 26 points of flattery over the hand-graded
269
- 63.2%). Six of this framework's releases (0.1.6–0.1.11) shipped from what
270
- these runs found -- and after five independent audit passes reshaped the
271
- emitter (0.1.17–0.1.21), the complaints engagement was built and implemented
272
- again on 0.1.21: green in round 2, holdout 76.7% against the original's
273
- 63.3%, the run committed beside the original for comparison. A sixth pass,
274
- widened to the exam, the components and the fine-tuning path, signed off
275
- the freeform shape with conditions and refused the decision shape for
276
- reasons that were the generator's; 0.1.22 answered each as a check first.
277
- A seventh pass found those checks holding and the shape-specific work
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 — every environment
485
- variable the code reads is documented, everything the systemd unit demands
486
- is created by a shipped installer, CI has a lane that goes green without a
487
- model, the smoke test passes on a fresh emission, the code is lint-clean,
488
- the payload path composes end to end and refuses garbage at the door, a
489
- caller cannot forge a result, a hostile document or a long query costs
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 and
542
- who put it there; adoption, time to first value, whatever the client
543
- measured. **`fde outcomes`** prints what the record shows without anyone's
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 an
591
- allowlist from the emitted `ops/agent-policy.yaml`, and no network
592
- unless someone with a name and a reason opened it. The implementation
593
- log records the image digest the agent actually ran on; without the
594
- sandbox it says the agent had the host.
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 and who put it there |
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 envelope follows the command's exit,
118
- never a reading of its text. Its contract is a JSON Schema, `fde mcp
119
- --schema`, that every reply is tested against; a client pins
120
- `schema_version`, which moves only when a field changes meaning or goes
121
- away, never when one is added. An engagement is named as `start` named
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,316 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 |
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
- [fde-demo-receipts](https://github.com/atulkapoor/fde-demo-receipts) —
211
- 626 scanned receipts through gates, build, and an agent-driven implement
212
- loop (`fde implement`, graded against held-out cases the agent never sees)
213
- whose holdout refused an overfit implementation and whose measured plateau
214
- flipped the design from rules to a model, reason on the record.
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 agent posture was
218
- decided from the facts, and the loop finished **green with the holdout
219
- passing** — the framework's first.
220
- [fde-demo-rfc-qa](https://github.com/atulkapoor/fde-demo-rfc-qa) —
221
- freeform QA over 58 real RFCs: 100% recall@10 on real queries, a green
222
- loop, and then the calibration gate **refusing its own judge** exactly as
223
- the prediction published beforehand said it would (73.7% agreement,
224
- refused; the judge's 89.5% was 26 points of flattery over the hand-graded
225
- 63.2%). Six of this framework's releases (0.1.6–0.1.11) shipped from what
226
- these runs found -- and after five independent audit passes reshaped the
227
- emitter (0.1.17–0.1.21), the complaints engagement was built and implemented
228
- again on 0.1.21: green in round 2, holdout 76.7% against the original's
229
- 63.3%, the run committed beside the original for comparison. A sixth pass,
230
- widened to the exam, the components and the fine-tuning path, signed off
231
- the freeform shape with conditions and refused the decision shape for
232
- reasons that were the generator's; 0.1.22 answered each as a check first.
233
- A seventh pass found those checks holding and the shape-specific work
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 — every environment
441
- variable the code reads is documented, everything the systemd unit demands
442
- is created by a shipped installer, CI has a lane that goes green without a
443
- model, the smoke test passes on a fresh emission, the code is lint-clean,
444
- the payload path composes end to end and refuses garbage at the door, a
445
- caller cannot forge a result, a hostile document or a long query costs
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 and
498
- who put it there; adoption, time to first value, whatever the client
499
- measured. **`fde outcomes`** prints what the record shows without anyone's
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 an
547
- allowlist from the emitted `ops/agent-policy.yaml`, and no network
548
- unless someone with a name and a reason opened it. The implementation
549
- log records the image digest the agent actually ran on; without the
550
- sandbox it says the agent had the host.
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 and who put it there |
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