Handbook
ContractSpec v2 (metadata alongside v1 Markdown)
LCDL task contracts ship as Markdown under:
Updated
src/forge_lcdl/contracts/<task_id>/<version>/contract.md
Sprint 1 adds an optional machine-readable sidecar:
src/forge_lcdl/contracts/<task_id>/<version>/contract.json
The Markdown file stays the narrative source for humans. The JSON file (when present) carries ContractSpec fields for tooling: schemas, success criteria, failure modes, and policy hints for cheap models, benchmarks, and future verifiers.
ContractSpec lifecycle flow
How contract Markdown and JSON sidecars load, verify, and publish into the reference handbook and catalog.
- contract.md + contract.jsonHuman narrative plus optional machine-readable ContractSpec sidecar.
- load_contract_specResolves a ContractSpec through forge_lcdl.contracts_api.
- audits + pytestCatalog audits and pytest enforce contract consistency.
- handbook HTML + catalog linksReference handbook and task catalog publish linked contract documentation.
contract.md + contract.json
|
v
load_contract_spec
|
v
audits + pytest
|
v
handbook HTML + catalog linksCoexistence with v1
- Directory names and layout are unchanged.
TaskRunnerandrun_taskbehavior are unchanged; they do not readcontract.jsonyet.- Tasks without
contract.jsonstill synthesize readable metadata forload_contract_spec(best-effort title from Markdown until a maintainer lands a sidecar). - Unknown
task_id/versionraisesUnknownContractError. - Artifact-only Markdown contracts (
interaction_probe,page_probe,validation_failure,page_mechanics) have norun_taskimplementation but still loadload_contract_specwhencontract.md/contract.jsonare present interchange docs.
API
Use forge_lcdl.contracts_api (src/forge_lcdl/contracts_api.py) — not a Python package named after the bundled contracts/ asset directory.
load_contract_spec(task_id, version="v1") -> ContractSpecvalidate_contract_input(spec, input_obj)/validate_contract_output(spec, output_obj)
ContractSpec fields
task_id,version,titleinput_schema/output_schema: JSON-Schema-like dicts (subset enforced by LCDL)success_criteria,failure_modes: lists of stringsretry_policy,verification_policy,fallback_policy: extensible dictscontract_markdown_path: relative path string matching the bundled layout (e.g.extract_schema_from_text/v1/contract.md)
contract.json format
Top-level object; use "contract_spec_format": 2 for the current metadata shape (format 1 in existing files is still accepted).
ContractSpec fields (v2)
All v1 fields, plus:
capabilities: extensible dict (e.g.uses_llm,supports_rag,returns_citations)execution_policy: dict (e.g.complexity,risk,max_attempts)inference_policy: dict (e.g.mode,min_confidence)rag_policy: dict (e.g.mode,top_k,require_citations,max_context_tokens)prompt_cache_policy: dict (e.g.enabled, stable/dynamic part hints)extensions: dict of unknown top-level keys preserved fromcontract.json(vendor-specific metadata)
Built-in defaults apply when contract.json omits these objects or when the spec is synthesized from Markdown-only tasks.
Unknown keys
Any top-level key in contract.json that is not part of the known ContractSpec mapping is stored in ContractSpec.extensions (not dropped).
Validation subset
validate_contract_input / validate_contract_output perform lightweight checks only (no jsonschema dependency):
- Top-level value must be a
dict. - If the schema has
required(list of strings), every key must be present. - If
propertiesmaps a key to{"type": "<json-schema-type>"}, when that key is present its value must match the shallow type (string,number,integer,boolean,object,array,null).
Nested object schemas are not fully validated in this sprint.
On failure, ContractValidationError is raised with a short message (missing keys or type mismatch).
Schema catalog and audits
- Narrative layering + L0–L4 maturity: SCHEMAS.md.
- Curated IDs for examples and audits: PRIORITY-CONTRACTS.md.
- Regenerate envelopes after materially changing payloads (maintainers):
python3 scripts/generate_contract_sidecars.py
python3 scripts/audit_contract_docs.py
python3 scripts/audit_contract_docs.py --strict
python3 scripts/audit_contract_docs.py --strict --strict-depth
Curated bundles listed in scripts/generate_contract_sidecars.py (CURATED_ONLY_MERGE_TASK_IDS) preserve hand-written success/failure text while enriching examples.
Import smoke test
Install paths match the rest of the library: use a venv and pip install -e ".[dev]" (see README), then run python / python3 as usual. On a clean checkout without an install, point Python at src/:
cd forge-lcdl
PYTHONPATH=src python3 - <<'PY'
from forge_lcdl.contracts_api import load_contract_spec
for task_id in [
"extract_schema_from_text",
"llm_boolean_gate",
"llm_enum_route",
"decompose_problem",
"plan_decision_pack",
]:
spec = load_contract_spec(task_id, "v1")
print(task_id, spec.version, bool(spec.output_schema))
PY
Packaging
Wheel/sdist include both contracts/**/*.md and contracts/**/*.json (see pyproject.toml).
See also
- SCHEMAS.md — kinds of schemas, interchange artifacts, audits, maturity ladder.
- PRIORITY-CONTRACTS.md — curated catalog subset for strict checks.