fde-framework 0.1.0__tar.gz → 0.1.2__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.0 → fde_framework-0.1.2}/CHANGELOG.md +34 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/PKG-INFO +106 -20
- {fde_framework-0.1.0 → fde_framework-0.1.2}/README.md +105 -19
- {fde_framework-0.1.0 → fde_framework-0.1.2}/pyproject.toml +1 -1
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/cli.py +113 -54
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/emit.py +34 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/gates.py +17 -10
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/implement.py +15 -4
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/registry.py +22 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_emit.py +9 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_sanitisation.py +20 -2
- {fde_framework-0.1.0 → fde_framework-0.1.2}/.gitignore +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/LICENSE +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/examples/invoice-extraction/README.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/ansible-playbook.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/assisted-deterministic.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/audit-only.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/boundary-and-audit.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/cascade.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/classical-ml.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/compose.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/decision-log.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/deterministic-masking.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/deterministic.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/direct-call.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/episodic-store.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/explainability-record.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/field-match.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/finetune.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/fixed-sequence.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/gitops.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/governed-tools.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/graph-retrieval.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/judged.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/keyword-search.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/kubernetes-manifests.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/labelled-metrics.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/llm-extraction.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/llm-scrubbing.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/llm.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/local-embedding.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/managed-api.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/managed-embedding.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/manual-runbook.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/model-planner.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/ocr-pipeline.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/optimisation-reasoning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/optimisation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/passthrough.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/role-scoped-authority.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/segmentation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/self-hosted.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/serverless-gpu.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/speech-transcription.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/structured-logs.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/systemd-unit.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/terraform-module.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/text-extraction.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/traced.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/vector-search.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/video-ingestion.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/windowed-ingestion.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/approaches/working-state.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/cases/churn-scoring.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/cases/route-planning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/cases/structured-extraction.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/cases/studio-style.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/accountability.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/deployment.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/embedding.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/evaluation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/governance.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/integration.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/memory.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/observability.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/perception.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/planning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/provisioning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/reasoning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/redaction.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/representation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/retrieval.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/components/serving.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/accelerator.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/access_model.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/arrival_rate.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/availability_target.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/cheap_path_coverage.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/confidence_calibrated.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/container_competence.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/corpus_size.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/data_residency.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/environment_lifetime.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/existing_cluster.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/existing_iac_tool.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/external_systems.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/hosting.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/human_waiting.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/input_format.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/interpretability_required.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/labelled_count.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/latency_budget_ms.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/licence_posture.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/operates_after_handover.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/output_shape.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/provisioning_api.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/query_pattern.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/recall_span.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/dimensions/sensitivity_present.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Generator.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Guard.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Mapper.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/ModelServer.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Parser.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Planner.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Retriever.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Scorer.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Store.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/ToolBoundary.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/interfaces/Tracer.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/locales/eu-gdpr.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/locales/in-dpdp.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/ansible-playbook.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/assisted-deterministic.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/audit-only.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/boundary-and-audit.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/cascade-reasoning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/cascade-representation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/cascade-retrieval.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/classical-ml-reasoning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/classical-ml.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/compose.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/decision-log.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/deterministic-masking.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/deterministic.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/direct-call.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/episodic-store.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/explainability-record.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/field-match.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/finetune-representation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/finetune.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/fixed-sequence.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/gitops.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/governed-tools.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/graph-retrieval.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/judged.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/keyword-search.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/kubernetes-manifests.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/labelled-metrics.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/llm-representation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/llm-scrubbing.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/llm.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/local-embedding.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/managed-api.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/managed-embedding.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/manual-runbook.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/model-planner.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/ocr-pipeline.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/optimisation-reasoning.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/optimisation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/passthrough.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/role-scoped-authority.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/segmentation.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/self-hosted.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/serverless-gpu.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/speech-transcription.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/structured-logs.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/systemd-unit.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/terraform-module.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/text-extraction.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/traced.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/vector-search.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/video-ingestion.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/windowed-ingestion.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/patterns/working-state.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/langgraph.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/local-judge.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/mcp.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/ollama.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/openai-judge.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/opentelemetry.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/ortools.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/pgvector.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/plain-python.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/qdrant.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/tesseract.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/vllm.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/whisper.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/stacks/xgboost.md +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/accountability/decision-log.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/accountability/explainability-record.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/deployment/compose.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/deployment/kubernetes-manifests.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/deployment/systemd-unit.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/embedding/local-embedding.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/embedding/managed-embedding.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/field-match.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/judged.local-judge.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/judged.openai-judge.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/judged.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/labelled-metrics.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/evaluation/labelled-metrics.xgboost.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/governance/audit-only.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/governance/boundary-and-audit.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/governance/role-scoped-authority.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/integration/direct-call.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/integration/governed-tools.mcp.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/integration/governed-tools.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/memory/episodic-store.pgvector.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/memory/episodic-store.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/memory/working-state.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/observability/structured-logs.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/observability/traced.opentelemetry.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/observability/traced.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/ocr-pipeline.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/ocr-pipeline.tesseract.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/passthrough.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/speech-transcription.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/speech-transcription.whisper.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/text-extraction.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/video-ingestion.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/perception/windowed-ingestion.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/planning/fixed-sequence.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/planning/model-planner.langgraph.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/planning/model-planner.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/planning/optimisation.ortools.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/planning/optimisation.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/provisioning/ansible-playbook.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/provisioning/gitops.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/provisioning/manual-runbook.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/provisioning/terraform-module.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/classical-ml.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/classical-ml.xgboost.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/finetune.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/llm.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/optimisation.ortools.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/reasoning/optimisation.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/redaction/deterministic-masking.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/redaction/llm-scrubbing.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/assisted.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/classical-ml.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/classical-ml.xgboost.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/deterministic.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/finetune.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/llm.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/representation/segmentation.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/cascade.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/graph-retrieval.pgvector.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/graph-retrieval.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/graph-retrieval.qdrant.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/keyword-search.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/vector-search.pgvector.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/vector-search.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/retrieval/vector-search.qdrant.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/serving/managed-api.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/serving/self-hosted.ollama.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/serving/self-hosted.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/serving/self-hosted.vllm.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/framework/templates/serving/serverless-gpu.plain.py.j2 +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/__init__.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/architect.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/costing.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/decide.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/decompose.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/deploy.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/evolution.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/factlog.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/graph.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/__init__.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/answers.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/documents.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/interview.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/llm_reader.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/prose.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/intake/samples.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/__init__.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/base.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/fact.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/profile.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/respondent.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/models/schema.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/moves.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/ops.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/predicate.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/realization.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/scan.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/space.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/src/fde/workflow.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/__init__.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/conftest.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/models/__init__.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/models/test_profile.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_access_and_sensitivity.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_answers.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cascade.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_engagement.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_evolution.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_gates.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_intake.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_kb.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_robustness.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_cli_samples.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_costing.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_coverage.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_dead_zones.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_decide.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_decompose.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_deploy.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_documents.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_embedding.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_evolution.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_factlog.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_gates.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_implement.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_interview.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_llm_reader.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_locales.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_memory_retrieval.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_more_templates.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_moves.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_multimodal.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_ops.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_package.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_prose.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_realization.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_registry.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_remaining.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_reversibility.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_samples.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_scan.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_schema.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_serving.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_shipped_registry.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_space.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_stack_swap.py +0 -0
- {fde_framework-0.1.0 → fde_framework-0.1.2}/tests/test_templates.py +0 -0
|
@@ -5,6 +5,40 @@ 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.2] — 2026-09-07
|
|
9
|
+
|
|
10
|
+
A fresh-eyes usability round, every finding verified in a clean venv:
|
|
11
|
+
|
|
12
|
+
- The hero quickstart runs verbatim: bare engagement names resolve
|
|
13
|
+
(`fde ask acme` finds `engagements/acme`), and `fde start` reads its
|
|
14
|
+
own statement through the prose reader, so the first minute shows
|
|
15
|
+
typed facts instead of "no facts recorded yet".
|
|
16
|
+
- `fde --version`; interview questions show their legal values with the
|
|
17
|
+
question; gate remedies name their clearing commands; the baseline
|
|
18
|
+
refusal names the exact keys that satisfy it.
|
|
19
|
+
- `fde implement` without an agent on PATH is a sentence with the fix,
|
|
20
|
+
never a traceback; `fde cost --price-per-seat` works without fleet
|
|
21
|
+
flags.
|
|
22
|
+
- kb subcommands take `--registry` (with `--root` kept as an alias).
|
|
23
|
+
- Every emitted project gets a front-door README; images are PNG so
|
|
24
|
+
they render on PyPI and mobile; the README gains a copy-paste full
|
|
25
|
+
lifecycle with the baseline YAML inline, and a Python API section
|
|
26
|
+
backed by the public `fde.registry.default_root()`.
|
|
27
|
+
|
|
28
|
+
## [0.1.1] — 2026-09-06
|
|
29
|
+
|
|
30
|
+
- README images render everywhere: absolute URLs, because PyPI does not
|
|
31
|
+
serve a repository's relative paths — and each release's page is frozen,
|
|
32
|
+
so the fix required this patch.
|
|
33
|
+
- A terminal demo card on the front page, rendered from real output,
|
|
34
|
+
refusal included on purpose.
|
|
35
|
+
- Social-preview image shipped in assets/.
|
|
36
|
+
|
|
37
|
+
## [0.1.0] — 2026-09-06
|
|
38
|
+
|
|
39
|
+
First public release on PyPI: `pip install fde-framework`. The registry
|
|
40
|
+
rides inside the wheel; a bare install knows everything the corpus knows.
|
|
41
|
+
|
|
8
42
|
### Added
|
|
9
43
|
- End-to-end pipeline: prose/document/sample/interview/hardware-scan intake →
|
|
10
44
|
append-only fact log with dimension-dependent provenance → permutation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: fde-framework
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: A framework for Forward Deployed Engineers: from problem statement to a deployable AI project, every decision traced to a fact.
|
|
5
5
|
Project-URL: Homepage, https://github.com/atulkapoor/fde-framework
|
|
6
6
|
Project-URL: Repository, https://github.com/atulkapoor/fde-framework
|
|
@@ -36,17 +36,28 @@ Requires-Dist: anthropic>=0.40; extra == 'llm'
|
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
38
|
<picture>
|
|
39
|
-
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.
|
|
40
|
-
<img src="assets/banner-light.
|
|
39
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/banner-dark.png">
|
|
40
|
+
<img src="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/banner-light.png" alt="fde — a framework for Forward Deployed Engineers" width="760">
|
|
41
41
|
</picture>
|
|
42
42
|
|
|
43
43
|
# fde — a framework for Forward Deployed Engineers
|
|
44
44
|
|
|
45
|
+
[](https://pypi.org/project/fde-framework/)
|
|
45
46
|
[](https://github.com/atulkapoor/fde-framework/actions/workflows/ci.yml)
|
|
46
|
-

|
|
48
|
+
[](https://pypistats.org/packages/fde-framework)
|
|
47
49
|

|
|
48
50
|
[](LICENSE)
|
|
49
51
|
|
|
52
|
+
<p>
|
|
53
|
+
<a href="#install">Install</a> ·
|
|
54
|
+
<a href="#try-it-in-two-minutes">Quickstart</a> ·
|
|
55
|
+
<a href="ARCHITECTURE.md">Architecture</a> ·
|
|
56
|
+
<a href="examples/invoice-extraction/">Worked example</a> ·
|
|
57
|
+
<a href="CONTRIBUTING.md">Contributing</a> ·
|
|
58
|
+
<a href="https://pypi.org/project/fde-framework/">PyPI</a>
|
|
59
|
+
</p>
|
|
60
|
+
|
|
50
61
|
**fde** is an open-source framework for Forward Deployed Engineers: it takes a
|
|
51
62
|
client engagement from a problem statement to a runnable, deployable AI
|
|
52
63
|
project — with every decision traced to a fact, and every fact traced to a
|
|
@@ -59,12 +70,18 @@ evidence, and code generation that ends in something you can actually deploy —
|
|
|
59
70
|
including on-premise, inside a customer VPC, or fully air-gapped.
|
|
60
71
|
|
|
61
72
|
```bash
|
|
73
|
+
pip install fde-framework
|
|
62
74
|
fde start acme --statement "Extract fields from supplier invoices."
|
|
63
75
|
fde ask acme --role admin # role-scoped discovery interview
|
|
64
76
|
fde architect acme # the design, with cited rationale
|
|
65
77
|
fde build acme --out project # code + evals + deploy assets + runbook
|
|
66
78
|
```
|
|
67
79
|
|
|
80
|
+
<img src="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/demo.png" alt="fde in a terminal: a paragraph becomes typed facts, an architecture with a fingerprint, and a build that refuses until the hard gate passes" width="780">
|
|
81
|
+
|
|
82
|
+
*That refusal at the end is the product working: no baseline, no verified data
|
|
83
|
+
access — no build. The remedies ship with every gate.*
|
|
84
|
+
|
|
68
85
|
## What it does
|
|
69
86
|
|
|
70
87
|
| | |
|
|
@@ -179,13 +196,23 @@ modules that raise with the reason attached, never as silent gaps.
|
|
|
179
196
|
|
|
180
197
|
## Install
|
|
181
198
|
|
|
182
|
-
Prerequisites: Python 3.11
|
|
199
|
+
Prerequisites: Python 3.11+.
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pip install fde-framework # the registry ships inside the wheel
|
|
203
|
+
fde start acme --statement "..." # works from any directory
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Extras: `pip install "fde-framework[documents]"` for PDF/docx intake, `[llm]`
|
|
207
|
+
for the hosted-model reader path.
|
|
208
|
+
|
|
209
|
+
Or from source (contributors — a local ./framework outranks the packaged copy):
|
|
183
210
|
|
|
184
211
|
```bash
|
|
185
212
|
git clone https://github.com/atulkapoor/fde-framework.git
|
|
186
213
|
cd fde-framework
|
|
187
214
|
python3 --version # must say 3.11+; an older python3 makes pip backtrack for ages instead of failing fast
|
|
188
|
-
python3 -m venv .venv && .venv/bin/pip install -e ".[dev,documents]"
|
|
215
|
+
python3 -m venv .venv && .venv/bin/pip install -e ".[dev,documents]"
|
|
189
216
|
```
|
|
190
217
|
|
|
191
218
|
Or with [uv](https://docs.astral.sh/uv/): `uv venv && uv pip install -e ".[dev,documents]"`
|
|
@@ -214,18 +241,18 @@ refuses by name and says exactly what to install.
|
|
|
214
241
|
## Try it
|
|
215
242
|
|
|
216
243
|
```bash
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
244
|
+
fde start acme --statement "Extract fields from supplier invoices."
|
|
245
|
+
fde ask engagements/acme --role admin # role-scoped interview
|
|
246
|
+
fde status engagements/acme # gates, gaps, disagreements
|
|
247
|
+
fde architect engagements/acme # the design, with rationale
|
|
248
|
+
fde build engagements/acme --out project # refuses until gates clear
|
|
249
|
+
|
|
250
|
+
fde scan engagements/acme # what this hardware runs
|
|
251
|
+
fde cost --requests-per-day 500000 --model-b 70 # dated fleet sizing
|
|
252
|
+
|
|
253
|
+
fde kb validate # parse and cross-link the registry
|
|
254
|
+
fde kb gaps --root framework # what the corpus is missing
|
|
255
|
+
fde kb sweep --root framework # profiles no approach can serve
|
|
229
256
|
.venv/bin/pytest -q
|
|
230
257
|
```
|
|
231
258
|
|
|
@@ -258,6 +285,66 @@ project/
|
|
|
258
285
|
└── COMPLIANCE.md # jurisdiction obligations, when a locale pack was applied
|
|
259
286
|
```
|
|
260
287
|
|
|
288
|
+
## The full lifecycle, copy-paste
|
|
289
|
+
|
|
290
|
+
Everything below runs from an empty directory after `pip install fde-framework`:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
fde start acme --statement "Extract fields from scanned supplier invoices; \
|
|
294
|
+
data cannot leave; 200,000 documents, 8,000 verified; a person is waiting."
|
|
295
|
+
# plays back the typed facts it read, and the three questions worth asking next
|
|
296
|
+
|
|
297
|
+
fde ask acme --role eval_owner # answer what discovery still needs
|
|
298
|
+
fde status acme # facts by scope, gates, % settled
|
|
299
|
+
|
|
300
|
+
cat > baseline.yaml <<'YAML'
|
|
301
|
+
volume: {value: 20000, unit: docs/month, definition: invoices received by AP}
|
|
302
|
+
cycle_time_per_unit_seconds: {value: 300, unit: s, definition: arrival to posted}
|
|
303
|
+
labour_hours_per_week: {value: 35, unit: h/week, definition: AP team keying time}
|
|
304
|
+
rework_rate: {value: 0.1, unit: ratio, definition: entries corrected after post}
|
|
305
|
+
exception_rate: {value: 0.07, unit: ratio, definition: routed to a human queue}
|
|
306
|
+
error_rate: {value: 0.04, unit: ratio, definition: wrong amount or vendor posted}
|
|
307
|
+
business_metric: {value: 9, unit: days, definition: mean days payable outstanding}
|
|
308
|
+
sampled: {n: 40, method: random invoices across two months}
|
|
309
|
+
YAML
|
|
310
|
+
fde baseline acme --file baseline.yaml
|
|
311
|
+
fde data-access acme --note "read replica returned 14 real rows"
|
|
312
|
+
fde security-review acme --note "client infosec walked the data paths"
|
|
313
|
+
fde ask acme --role eval_owner # or: fde waive acme client_readiness --reason "..."
|
|
314
|
+
|
|
315
|
+
fde build acme --out project # refuses until the gates truly pass
|
|
316
|
+
python project/evals/harness.py # red until implemented -- that's the exam
|
|
317
|
+
fde implement project # drive a coding agent until it's green
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Python API
|
|
321
|
+
|
|
322
|
+
The CLI is a thin layer; everything is importable. The registry loads from the
|
|
323
|
+
installed wheel, so this runs anywhere:
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
from fde.architect import architect
|
|
327
|
+
from fde.intake.prose import parse_prose
|
|
328
|
+
from fde.models.profile import Profile
|
|
329
|
+
from fde.registry import default_root, load_registry
|
|
330
|
+
|
|
331
|
+
registry = load_registry(default_root())
|
|
332
|
+
|
|
333
|
+
profile = Profile()
|
|
334
|
+
profile.ingest(parse_prose(
|
|
335
|
+
"500,000 scanned invoices; data cannot leave; 10,000 verified; "
|
|
336
|
+
"a person is waiting; structured records out.", registry))
|
|
337
|
+
|
|
338
|
+
design = architect(profile, registry)
|
|
339
|
+
print(design.topology) # customer-vpc
|
|
340
|
+
for component, decision in sorted(design.decisions.items()):
|
|
341
|
+
if decision.approach:
|
|
342
|
+
print(component, decision.approach, decision.rationale)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
Every decision object carries its rationale and its rejected alternatives —
|
|
346
|
+
the same receipts the emitted `ARCHITECTURE.md` prints.
|
|
347
|
+
|
|
261
348
|
## Common commands
|
|
262
349
|
|
|
263
350
|
| | |
|
|
@@ -410,9 +497,8 @@ The registry is the shared asset; engagements are private working state.
|
|
|
410
497
|
- **Rule revision from outcomes** — capture is wired end to end; revision
|
|
411
498
|
deliberately waits for a corpus of measured retrospectives rather than
|
|
412
499
|
pretending a handful is evidence.
|
|
413
|
-
- **PyPI release** — after the first tagged version.
|
|
414
500
|
- **More locale packs and stacks** — both are data; contributions enter
|
|
415
|
-
against [CONTRIBUTING.md](CONTRIBUTING.md)'s contract.
|
|
501
|
+
against [CONTRIBUTING.md](CONTRIBUTING.md)'s contract (and the [code of conduct](CODE_OF_CONDUCT.md)).
|
|
416
502
|
- **Language, channel, and device axes** — six of twenty industry test
|
|
417
503
|
statements named regional languages, low bandwidth, or basic devices;
|
|
418
504
|
the honest wiring (per-language evaluation, SMS/IVR serving approaches,
|
|
@@ -1,15 +1,26 @@
|
|
|
1
1
|
<picture>
|
|
2
|
-
<source media="(prefers-color-scheme: dark)" srcset="assets/banner-dark.
|
|
3
|
-
<img src="assets/banner-light.
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/banner-dark.png">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/banner-light.png" alt="fde — a framework for Forward Deployed Engineers" width="760">
|
|
4
4
|
</picture>
|
|
5
5
|
|
|
6
6
|
# fde — a framework for Forward Deployed Engineers
|
|
7
7
|
|
|
8
|
+
[](https://pypi.org/project/fde-framework/)
|
|
8
9
|
[](https://github.com/atulkapoor/fde-framework/actions/workflows/ci.yml)
|
|
9
|
-

|
|
11
|
+
[](https://pypistats.org/packages/fde-framework)
|
|
10
12
|

|
|
11
13
|
[](LICENSE)
|
|
12
14
|
|
|
15
|
+
<p>
|
|
16
|
+
<a href="#install">Install</a> ·
|
|
17
|
+
<a href="#try-it-in-two-minutes">Quickstart</a> ·
|
|
18
|
+
<a href="ARCHITECTURE.md">Architecture</a> ·
|
|
19
|
+
<a href="examples/invoice-extraction/">Worked example</a> ·
|
|
20
|
+
<a href="CONTRIBUTING.md">Contributing</a> ·
|
|
21
|
+
<a href="https://pypi.org/project/fde-framework/">PyPI</a>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
13
24
|
**fde** is an open-source framework for Forward Deployed Engineers: it takes a
|
|
14
25
|
client engagement from a problem statement to a runnable, deployable AI
|
|
15
26
|
project — with every decision traced to a fact, and every fact traced to a
|
|
@@ -22,12 +33,18 @@ evidence, and code generation that ends in something you can actually deploy —
|
|
|
22
33
|
including on-premise, inside a customer VPC, or fully air-gapped.
|
|
23
34
|
|
|
24
35
|
```bash
|
|
36
|
+
pip install fde-framework
|
|
25
37
|
fde start acme --statement "Extract fields from supplier invoices."
|
|
26
38
|
fde ask acme --role admin # role-scoped discovery interview
|
|
27
39
|
fde architect acme # the design, with cited rationale
|
|
28
40
|
fde build acme --out project # code + evals + deploy assets + runbook
|
|
29
41
|
```
|
|
30
42
|
|
|
43
|
+
<img src="https://raw.githubusercontent.com/atulkapoor/fde-framework/main/assets/demo.png" alt="fde in a terminal: a paragraph becomes typed facts, an architecture with a fingerprint, and a build that refuses until the hard gate passes" width="780">
|
|
44
|
+
|
|
45
|
+
*That refusal at the end is the product working: no baseline, no verified data
|
|
46
|
+
access — no build. The remedies ship with every gate.*
|
|
47
|
+
|
|
31
48
|
## What it does
|
|
32
49
|
|
|
33
50
|
| | |
|
|
@@ -142,13 +159,23 @@ modules that raise with the reason attached, never as silent gaps.
|
|
|
142
159
|
|
|
143
160
|
## Install
|
|
144
161
|
|
|
145
|
-
Prerequisites: Python 3.11
|
|
162
|
+
Prerequisites: Python 3.11+.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pip install fde-framework # the registry ships inside the wheel
|
|
166
|
+
fde start acme --statement "..." # works from any directory
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Extras: `pip install "fde-framework[documents]"` for PDF/docx intake, `[llm]`
|
|
170
|
+
for the hosted-model reader path.
|
|
171
|
+
|
|
172
|
+
Or from source (contributors — a local ./framework outranks the packaged copy):
|
|
146
173
|
|
|
147
174
|
```bash
|
|
148
175
|
git clone https://github.com/atulkapoor/fde-framework.git
|
|
149
176
|
cd fde-framework
|
|
150
177
|
python3 --version # must say 3.11+; an older python3 makes pip backtrack for ages instead of failing fast
|
|
151
|
-
python3 -m venv .venv && .venv/bin/pip install -e ".[dev,documents]"
|
|
178
|
+
python3 -m venv .venv && .venv/bin/pip install -e ".[dev,documents]"
|
|
152
179
|
```
|
|
153
180
|
|
|
154
181
|
Or with [uv](https://docs.astral.sh/uv/): `uv venv && uv pip install -e ".[dev,documents]"`
|
|
@@ -177,18 +204,18 @@ refuses by name and says exactly what to install.
|
|
|
177
204
|
## Try it
|
|
178
205
|
|
|
179
206
|
```bash
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
207
|
+
fde start acme --statement "Extract fields from supplier invoices."
|
|
208
|
+
fde ask engagements/acme --role admin # role-scoped interview
|
|
209
|
+
fde status engagements/acme # gates, gaps, disagreements
|
|
210
|
+
fde architect engagements/acme # the design, with rationale
|
|
211
|
+
fde build engagements/acme --out project # refuses until gates clear
|
|
212
|
+
|
|
213
|
+
fde scan engagements/acme # what this hardware runs
|
|
214
|
+
fde cost --requests-per-day 500000 --model-b 70 # dated fleet sizing
|
|
215
|
+
|
|
216
|
+
fde kb validate # parse and cross-link the registry
|
|
217
|
+
fde kb gaps --root framework # what the corpus is missing
|
|
218
|
+
fde kb sweep --root framework # profiles no approach can serve
|
|
192
219
|
.venv/bin/pytest -q
|
|
193
220
|
```
|
|
194
221
|
|
|
@@ -221,6 +248,66 @@ project/
|
|
|
221
248
|
└── COMPLIANCE.md # jurisdiction obligations, when a locale pack was applied
|
|
222
249
|
```
|
|
223
250
|
|
|
251
|
+
## The full lifecycle, copy-paste
|
|
252
|
+
|
|
253
|
+
Everything below runs from an empty directory after `pip install fde-framework`:
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
fde start acme --statement "Extract fields from scanned supplier invoices; \
|
|
257
|
+
data cannot leave; 200,000 documents, 8,000 verified; a person is waiting."
|
|
258
|
+
# plays back the typed facts it read, and the three questions worth asking next
|
|
259
|
+
|
|
260
|
+
fde ask acme --role eval_owner # answer what discovery still needs
|
|
261
|
+
fde status acme # facts by scope, gates, % settled
|
|
262
|
+
|
|
263
|
+
cat > baseline.yaml <<'YAML'
|
|
264
|
+
volume: {value: 20000, unit: docs/month, definition: invoices received by AP}
|
|
265
|
+
cycle_time_per_unit_seconds: {value: 300, unit: s, definition: arrival to posted}
|
|
266
|
+
labour_hours_per_week: {value: 35, unit: h/week, definition: AP team keying time}
|
|
267
|
+
rework_rate: {value: 0.1, unit: ratio, definition: entries corrected after post}
|
|
268
|
+
exception_rate: {value: 0.07, unit: ratio, definition: routed to a human queue}
|
|
269
|
+
error_rate: {value: 0.04, unit: ratio, definition: wrong amount or vendor posted}
|
|
270
|
+
business_metric: {value: 9, unit: days, definition: mean days payable outstanding}
|
|
271
|
+
sampled: {n: 40, method: random invoices across two months}
|
|
272
|
+
YAML
|
|
273
|
+
fde baseline acme --file baseline.yaml
|
|
274
|
+
fde data-access acme --note "read replica returned 14 real rows"
|
|
275
|
+
fde security-review acme --note "client infosec walked the data paths"
|
|
276
|
+
fde ask acme --role eval_owner # or: fde waive acme client_readiness --reason "..."
|
|
277
|
+
|
|
278
|
+
fde build acme --out project # refuses until the gates truly pass
|
|
279
|
+
python project/evals/harness.py # red until implemented -- that's the exam
|
|
280
|
+
fde implement project # drive a coding agent until it's green
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Python API
|
|
284
|
+
|
|
285
|
+
The CLI is a thin layer; everything is importable. The registry loads from the
|
|
286
|
+
installed wheel, so this runs anywhere:
|
|
287
|
+
|
|
288
|
+
```python
|
|
289
|
+
from fde.architect import architect
|
|
290
|
+
from fde.intake.prose import parse_prose
|
|
291
|
+
from fde.models.profile import Profile
|
|
292
|
+
from fde.registry import default_root, load_registry
|
|
293
|
+
|
|
294
|
+
registry = load_registry(default_root())
|
|
295
|
+
|
|
296
|
+
profile = Profile()
|
|
297
|
+
profile.ingest(parse_prose(
|
|
298
|
+
"500,000 scanned invoices; data cannot leave; 10,000 verified; "
|
|
299
|
+
"a person is waiting; structured records out.", registry))
|
|
300
|
+
|
|
301
|
+
design = architect(profile, registry)
|
|
302
|
+
print(design.topology) # customer-vpc
|
|
303
|
+
for component, decision in sorted(design.decisions.items()):
|
|
304
|
+
if decision.approach:
|
|
305
|
+
print(component, decision.approach, decision.rationale)
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Every decision object carries its rationale and its rejected alternatives —
|
|
309
|
+
the same receipts the emitted `ARCHITECTURE.md` prints.
|
|
310
|
+
|
|
224
311
|
## Common commands
|
|
225
312
|
|
|
226
313
|
| | |
|
|
@@ -373,9 +460,8 @@ The registry is the shared asset; engagements are private working state.
|
|
|
373
460
|
- **Rule revision from outcomes** — capture is wired end to end; revision
|
|
374
461
|
deliberately waits for a corpus of measured retrospectives rather than
|
|
375
462
|
pretending a handful is evidence.
|
|
376
|
-
- **PyPI release** — after the first tagged version.
|
|
377
463
|
- **More locale packs and stacks** — both are data; contributions enter
|
|
378
|
-
against [CONTRIBUTING.md](CONTRIBUTING.md)'s contract.
|
|
464
|
+
against [CONTRIBUTING.md](CONTRIBUTING.md)'s contract (and the [code of conduct](CODE_OF_CONDUCT.md)).
|
|
379
465
|
- **Language, channel, and device axes** — six of twenty industry test
|
|
380
466
|
statements named regional languages, low bandwidth, or basic devices;
|
|
381
467
|
the honest wiring (per-language evaluation, SMS/IVR serving approaches,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# Distribution name matches the repository and stays unique on any index;
|
|
3
3
|
# the import package and the CLI command remain the short `fde`.
|
|
4
4
|
name = "fde-framework"
|
|
5
|
-
version = "0.1.
|
|
5
|
+
version = "0.1.2"
|
|
6
6
|
description = "A framework for Forward Deployed Engineers: from problem statement to a deployable AI project, every decision traced to a fact."
|
|
7
7
|
readme = "README.md"
|
|
8
8
|
license = {text = "Apache-2.0"}
|