14. FACET v2.1.3 Migration Checklist
Status: Final
Target: FACET v2.1.3 REC-PROD (2026-02-19)
Current baseline: FACET v2.0 codebase (facet-compiler main branch)
Progress
- Iteration 133 completed:
closed remaining warning debt so workspace test output is clean (removed unused imports/vars in
crates/fct-parser/src/test_parser.rs,crates/fct-parser/tests/parser_tests.rs,crates/fct-resolver/src/lib.rs,crates/fct-engine/src/test_reporter.rs); compressed and updated docs entrypoints (docs/README.md,docs/index.md) and replaced stale v2.0 wording/legacy spec links acrossdocs/*.mdto point to../FACET-v2.1.3-Production-Language-Specification.md; added automated compliance summary generatorscripts/generate_compliance_report.py; integrated compliance artifact publishing into CI (.github/workflows/ci.yml, jobcompliance-report), and made release tags block on a mandatory quality gate (.github/workflows/release.yml, jobquality-gate) runningcargo test -q --workspace+ spec smoke/matrix + compliance report generation before release packaging. Verified withcargo test -q --workspace,cargo build -q --release --bin facet-fct,./scripts/smoke_examples_spec.sh ./target/release/facet-fct,./scripts/spec_matrix_examples.sh ./target/release/facet-fct, andpython3 scripts/generate_compliance_report.py --checklist docs/14-v2.1.3-migration-checklist.md --output compliance-report.md. - Iteration 132 completed:
closed explicit-message-id role regression in end-to-end runtime/render path:
Sectionnow carries canonical role metadata (crates/fct-engine/src/box_model.rs,.with_role(...)),run/inspect/TestRunnernow materialize role from facet kind when building sections (src/commands/run.rs,src/commands/inspect.rs,crates/fct-engine/src/test_runner.rs), and renderer now resolves message role from section role metadata with id-prefix fallback (crates/fct-render/src/lib.rs) so custom section ids no longer collapse to user-role during canonical emission. Added regressionstest_render_uses_explicit_section_role_when_id_is_custom(crates/fct-render/src/lib.rs) and role assertions indoc_to_sections_*tests (src/commands/run.rs). Also hardened spec example matrix automation:scripts/spec_matrix_examples.shnow suppresses host logs and extracts canonical JSON deterministically forjq, andexamples/spec/07_policy_conditions.facetnow has explicittool_exposedeny for deterministic matrix behavior independent of host default policy. Verified withcargo test -q --workspace,cargo build -q --release --bin facet-fct,./scripts/smoke_examples_spec.sh ./target/release/facet-fct, and./scripts/spec_matrix_examples.sh ./target/release/facet-fct. - Iteration 131 completed:
added spec-aligned end-to-end example suite under
examples/spec/(01..12, simple -> complex) with executable smoke runnerscripts/smoke_examples_spec.sh; fixed compiler/spec parity gaps found by running examples: parser now accepts spec@test "name"syntax incrates/fct-parser/src/parser.rs(+ regressions incrates/fct-parser/src/parser.rsandcrates/fct-parser/tests/syntax_matrix_tests.rs), listmaplens now supports Appendix A stylemap(field="...")incrates/fct-std/src/lenses/list.rs(+ unit tests), resolver no longer false-flags valid relative imports as symlink escape whenbase_dir/allowed_rootsare relative incrates/fct-resolver/src/lib.rs(+ regressiontest_relative_base_and_allowed_root_resolve_without_double_join); verified with./scripts/smoke_examples_spec.sh,cargo test -q -p fct-parser,cargo test -q -p fct-std,cargo test -q -p fct-resolver test_relative_base_and_allowed_root_resolve_without_double_join, andcargo test -q --workspace. - Iteration 130 completed:
aligned validator-facing standard lens signatures with FACET v2.1.3 Appendix A (
splitrequired arg, addedjson|keys|values|map(field)|sort_by|default|ensure_list) incrates/fct-ast/src/lens_signatures.rs, plus regression coverage incrates/fct-validator/src/checker.rs(appendix_a_standard_lenses_are_available_in_validator_registry); verified withcargo fmt --all,cargo test -q -p fct-validator checker::tests::appendix_a_standard_lenses_are_available_in_validator_registry,cargo test -q -p fct-parser,cargo test -q -p fct-validator,cargo test -q --workspace,cargo clippy --all-targets --all-features -- -D warnings. - Iteration 1 completed: parser normalization and lexical hardening started.
- Iteration 2 completed:
profile-aware
F801enforcement and strict attribute atoms in parser. - Iteration 3 completed: Phase 1 resolver baseline aligned for v2.1.3 merge/import determinism.
- Iteration 4 completed:
validator import checks switched from heuristics to real resolver (
F601/F602). - Iteration 5 completed:
AST map structures moved to ordered maps (
IndexMap) end-to-end. - Iteration 6 completed:
introduced shared
facet_version=2.1.3andpolicy_version=1constants. - Iteration 7 completed:
added normalized-source
document_hashhelper andinspectoutput. - Iteration 8 completed:
render metadata now carries
document_hashandpolicy_version; added NFC deterministic canonical-output test. - Iteration 9 completed:
render metadata aligned with required v2.1.3 fields (
facet_version/profile/mode/host_profile_id/budget_units/target_provider_id) with compatibility fields retained; added automaticpolicy_hashcomputation from effective@policyenvelope{policy_version, policy}. - Iteration 10 completed:
canonical payload now includes
messagesfield with deterministic role-group ordering (system -> user -> assistant) while legacy split message arrays remain for compatibility. - Iteration 11 completed:
to_json_compactnow emits canonical key-sorted deterministic JSON (JCS-equivalent serialization path) and includes regression test for deterministic bytes/key order. - Iteration 12 completed: Token Box allocation now preserves original section encounter order in outputs (removed id-based reordering, tie-break switched to source order) with new regression tests for both compressed and non-compressed paths.
- Iteration 13 completed:
R-DAG topological traversal made deterministic by merged
@varsfirst-insertion order; overrides keep canonical position; unknown@varsdependencies now fail withF401in Phase 3 path. - Iteration 14 completed:
runtime variable path traversal added for Phase 3 (
$x.a.b), withF405on missing field andF452on numeric path indexing ($x.0) per v2.1.3 path semantics. - Iteration 15 completed:
CLI
buildandrunmoved from TODO stubs to executable pipelines:build = parse+resolve+validate,run = parse+resolve+validate+R-DAG+layout+render, withrunemitting canonical JSON. - Iteration 16 completed:
fct runnow supports mode flags--pure|--exec(mutually exclusive) and emits selected mode in canonical metadata. - Iteration 17 completed:
Phase-2
@policyvalidator added: strict top-level keys, PolicyRule schema/type checks, op enum checks, requirednamechecks for tool/lens ops, matcher/canonical-name validation baseline, and PolicyCond structure validation withF401/F452diagnostics. - Iteration 18 completed:
PolicyCond variable typing strengthened: non-boolean condition varrefs now fail with
F451in validator Phase 2. - Iteration 19 completed:
R-DAG now enforces execution mode policy for lens trust levels in pure mode:
Level-1 (
Bounded) ->F803cache-only miss path, Level-2 (Volatile) ->F801disallowed, Level-0 allowed. - Iteration 20 completed:
Interface/system-tools baseline conformance: validator now rejects duplicate interfaces/functions/params and unknown
@system.toolsrefs (F452); renderer emits tools from@system.toolsunion (not all interfaces). - Iteration 21 completed:
renderer now applies baseline
tool_exposepolicy filtering (deny-first then allow by matcher) before emittingcanonical.tools. - Iteration 22 completed:
runtime guard trace skeleton added for
tool_expose: renderer can now produceGuardDecisionevents, emits deterministic deny asF454, and fail-closed undecidable guard state asF455. - Iteration 23 completed:
fct runnow emitsexecution.jsonartifact with metadata, guard events, and provenancehash_chain.headcomputed from spec seed fields (including profile/mode/policy_version) and chained event hashing. - Iteration 24 completed:
validator Phase-2 body semantics expanded:
@metaatoms/control-char checks,@contextbudget/defaults schema checks, message schema (contentrequired +whentyping withF451), and@input(...)placement/schema enforcement in@varswith new conformance tests. - Iteration 25 completed:
engine runtime
@input(...)materialization implemented in Phase 3 (ExecutionContext.runtime_inputs): supplied value/default selection, required-input failure, and runtime type checks now emitF453; CLIfct runcan pass runtime inputs via--runtime-input <json>. - Iteration 27 completed:
fct runnow resolves messagecontentvariable references from computed Phase-3 variables before Token Box layout, fixing end-to-end flow@input -> @vars -> message content -> render. - Iteration 28 completed:
tool_exposeguard evaluator in renderer now applies conjunctive rule matching foreffectand supportsPolicyCondruntime evaluation with short-circuit semantics (not/all/any), including undecidable (F455) handling only on actually evaluated branches. - Iteration 29 completed:
renderer now enforces and records
message_emitguard decisions (allow/deny) with deterministicinput_hash, applies policy rules before message inclusion, and fails closed withF455on undecidable message policy evaluation. - Iteration 30 completed:
guard evaluator now supports deterministic
@policy.defaultshandling fortool_exposeandmessage_emit(allow|deny|bool), with invalid default config treated as fail-closed undecidable (F455). - Iteration 31 completed:
Phase-3
lens_callruntime guard is now implemented in R-DAG for guarded trust levels (exec Level-1, all Level-2 entrypoint), including policy evaluation (deny/allow/defaults), short-circuitPolicyCond, deterministicinput_hash, and explicitF454/F455outcomes;fct runnow merges guard decisions from engine+renderer intoexecution.json. - Iteration 32 completed:
tool_callguard core implemented inToolExecutor(evaluate_tool_call_guard/execute_with_guard): deterministic policy matching (deny/allow/defaults), conjunctiveeffectfilter, short-circuitPolicyCond, deterministicinput_hash, andF454/F455fail-closed outcomes with guard decision emission. - Iteration 33 completed:
@test inputplumbing added end-to-end (AST -> parser -> TestRunner): test input map is parsed, materialized intoExecutionContext.runtime_inputs, and now influences policy/guard decisions for mockedtool_callflows with regression tests. - Iteration 34 completed:
Test assertion context expanded with structured
canonicalandexecutionobjects inTestRunner; path-based targets likecanonical.messages[0].roleandexecution.provenance.events[0].opare now evaluable in existing assertion kinds. - Iteration 35 completed:
TestResult/reporting extended with optionalcanonical_outputandexecution_output;fct testfailure-path construction and JSON reporter now carry these artifacts alongsiderendered_output. - Iteration 36 completed:
fct testgained mode flags--pure|--execand passes mode intoTestRunner; pure mode now fails mockedtool_callattempts withF801to enforce runtime I/O prohibition in tests. - Iteration 37 completed:
Added pure-mode bounded-lens test coverage in
TestRunner:@varspipeline with Level-1 lens now deterministically fails withF803in--puremode. - Iteration 38 completed:
Added isolation regression for
run_all: per-test runtime contexts do not leak@inputvalues across test cases (F453correctly raised in subsequent test without required input). - Iteration 39 completed:
Parser
@testspecialized body grammar expanded for multiline sections (vars/input/mock/assert), including unquoted FQ mock keys (e.g.WeatherAPI.get_current) and expression-style assertions (==,!=,contains,<,>). - Iteration 40 completed:
@test.varsnow applies as a deterministic override@varsblock, validates against declared@var_typesat test runtime (F451/F452), and re-computes dependent variables with regression tests. - Iteration 41 completed:
added explicit
@testmode/policy interaction matrix coverage fortool_callpaths: exec default deny ->F454, exec undecidable condition ->F455, pure mode tool call prohibition ->F801. - Iteration 42 completed:
Phase-2
@policyname validation now cross-checkstool_expose/tool_callnames against declared@interface.<fn>identifiers (including wildcard interface matchers), with dedicated validator tests for unknown interface/function and condition-typing cases with real interfaces. - Iteration 43 completed:
strengthened Phase-2
@policy.defaultsschema validation: only standard operation keys are allowed and values must beboolor stringallow|deny; added validator conformance tests for valid/invalid defaults maps. - Iteration 44 completed:
lens_callruntime guard now carries and validates lenseffect_class(Level-1/2 missing/invalid ->F456on first use), includes effect inGuardDecision, and applies conjunctive policyeffectmatching for lens operations. - Iteration 45 completed:
Phase-2
@policyname validation forlens_callnow cross-checks exact and.*prefix matchers against known lens registry entries, with regression tests for unknown and valid matchers. - Iteration 46 completed:
Phase-2
@policyname validation formessage_emitnow cross-checks against effective message identifiers (explicitidor derived<role>#<n>), including wildcard prefix matchers. - Iteration 47 completed:
completed conjunctive-policy parity coverage for
message_emit: renderer now has explicit regression provingeffectacts as an AND filter (nullOpDesc.effect_class=> rule does not match), aligning with existingtool_expose/tool_call/lens_callpaths. - Iteration 48 completed:
tool_exposeguard now carries real tooleffect_classfrom@interface fn effect; policyeffectmatcher is evaluated against that class and guard events record it, with new deny-on-match and mismatch regression tests. - Iteration 49 completed:
added canonical-message ordering regression for interleaved section input, proving role grouping (
system -> user -> assistant) while preserving within-role encounter order. - Iteration 50 completed:
runtime unknown-lens handling aligned to spec error code
F802:RDagEngineandTokenBoxModelnow emit dedicatedUnknownLensinstead of misclassifying asF801. - Iteration 51 completed:
added regression coverage for runtime
F802paths: unknown lens in@varspipeline (R-DAG) and unknown compression strategy lens (Token Box Model) now have explicit failing tests. - Iteration 52 completed:
message
whengating is now applied before section emission in mainrunandTestRunnerpipelines (including canonical test view), sowhen=falseblocks are omitted prior tomessage_emitguard evaluation. - Iteration 53 completed:
fct rundocument hash seed moved from pre-resolve source to resolved document canonical form (imports/merge already applied), emitted assha256:hash. - Iteration 54 completed:
layout sizing switched to FACET Units in active runtime paths:
TokenBoxModelnow measures post-strategy sizes with NFC+LF UTF-8 byte length, andrun/TestRunnersectionbase_sizeusescount_facet_units_in_value. - Iteration 55 completed:
section id derivation for message blocks is now centralized via shared helper (
derive_message_section_id) and used by bothrunandTestRunner, eliminating divergent local formatting paths. - Iteration 56 completed:
switched canonical JSON serialization to RFC 8785 JCS via
serde_json_canonicalizeracrossrun, renderer, and engine hash paths (lens_call/tool_callinput hashes), with regression test for numeric canonical form (12e1 -> 120). - Iteration 57 completed:
document_hashinfct runnow hashes bytes of Resolved Source Form (imports expanded in-place, NFC+LF normalized) viaResolver::resolve_source_formin [crates/fct-resolver/src/lib.rs] and hashing in [src/commands/run.rs]; regression tests:test_resolve_source_form_expands_imports_in_place,test_resolve_source_form_normalizes_crlf_and_nested_imports(cargo test -q -p fct-resolver), thencargo test -q --workspace. - Iteration 58 completed:
added explicit Phase-1 output API in resolver (
Phase1Output+Resolver::resolve_phase1) that returns bothresolved_source_formandresolved_ast; regression testtest_resolve_phase1_returns_source_and_astin [crates/fct-resolver/src/lib.rs], verified withcargo test -q -p fct-resolverandcargo test -q --workspace. - Iteration 59 completed:
completed Core-profile
F801fixture coverage for Hypervisor-only@varsconstructs by adding testscore_profile_rejects_input_directive_in_varsandcore_profile_rejects_pipeline_in_varsin [tests/profile_tests.rs], then validated viacargo test -q --workspace. - Iteration 60 completed:
confirmed strict 2-space indentation enforcement (
F001) with parser teststest_wrong_indentation_f001,test_mixed_indentation_f001in [crates/fct-parser/src/parser.rs] and end-to-end guard in [tests/integration_test.rs] (Should fail on bad indentation (F001)), validated bycargo test -q --workspace. - Iteration 61 completed:
confirmed full-syntax parse path for Core profile (
varrefandpipelineparsed first, then rejected by profile enforcement asF801) with testscore_profile_rejects_non_literal_varsandcore_profile_rejects_pipeline_in_varsin [tests/profile_tests.rs], validated bycargo test -q --workspace. - Iteration 62 completed:
added parser regression
test_inline_list_and_map_literals_parsein [crates/fct-parser/src/parser.rs] for positive inline list/map (including nested inline map) and validated withcargo test -q --workspace. - Iteration 63 completed:
finalized
@input(...)placement enforcement coverage with regressionsinput_not_allowed_inside_lens_argumentsandinput_not_allowed_outside_vars_value_positionin [tests/facet_semantics_tests.rs], complementing existing base/nested/default checks; validated bycargo test -q --workspace. - Iteration 64 completed:
added parser regressions
test_span_coordinates_equivalent_for_lf_and_crlfandtest_span_coordinates_equivalent_for_nfc_variantsin [crates/fct-parser/src/parser.rs] to prove span coordinates are computed on normalized NFC+LF source (aligned with existing normalized hash tests); validated bycargo test -q --workspace. - Iteration 65 completed:
added AST determinism snapshot regressions
test_ast_snapshot_is_deterministic_for_same_sourceandtest_ast_snapshot_is_deterministic_for_nfc_equivalent_inputsin [crates/fct-parser/src/parser.rs], validating stable AST serialization across repeated runs and NFC-equivalent inputs; verified withcargo test -q --workspace. - Iteration 66 completed:
added lexical fixture matrix tests in [
crates/fct-parser/tests/lexical_matrix_tests.rs] (lexical_positive_matrix,lexical_negative_matrix) to exercise identifier/string/escape/scalar and error-code paths (F003,F002), then validated viacargo test -q --workspace. - Iteration 67 completed:
added execution-artifact metadata schema regression
execution_artifact_metadata_has_required_fieldsin [src/commands/run.rs] to verify Appendix F required metadata fields (facet_version,host_profile_id,document_hash,policy_hash,policy_version) and exact field set; validated bycargo test -q --workspace. - Iteration 68 completed:
enforced GuardDecision sequence normalization (contiguous
seqstarting at 1) in artifact builder and added schema/sequence regressionsexecution_artifact_events_are_resequenced_without_gapsandexecution_artifact_event_has_required_schema_fieldsin [src/commands/run.rs], validated bycargo test -q --workspace. - Iteration 69 completed:
completed per-operation
input_hashcoverage and spec alignment:tool_exposehash input now follows Appendix F interface envelope in [crates/fct-render/src/lib.rs], and deterministic hash regressions were added fortool_call([crates/fct-engine/src/tool_executor.rs]),lens_call([crates/fct-engine/src/r_dag.rs]),tool_expose+message_emit([crates/fct-render/src/lib.rs]), and artifact event preservation ([src/commands/run.rs]); validated bycargo test -q --workspace. - Iteration 70 completed:
canonical message ordering proof was extended with drop-path coverage in renderer (
test_render_preserves_order_when_sections_are_dropped) in [crates/fct-render/src/lib.rs], confirming role-group ordering and within-role order stability even when layout drops sections; validated bycargo test -q --workspace. - Iteration 71 completed:
added execution artifact verifier regressions in [
src/commands/run.rs] (execution_artifact_hash_chain_replay_matches_head,execution_artifact_hash_chain_changes_on_event_tamper) to replay hash chain and detect tampering, closing Appendix F integrity proof; validated bycargo test -q --workspace. - Iteration 72 completed:
implemented optional attestation envelope validation/serialization in execution artifact builder (
build_execution_artifact_with_attestation+ envelope validator) with regression tests for valid envelope and invalidalgo/sigin [src/commands/run.rs]; validated bycargo test -q --workspace. - Iteration 73 completed:
added run-command artifact emission regression
execute_run_writes_execution_json_artifactin [src/commands/run.rs] to verifyfct runwritesexecution.jsonwith required top-level provenance structure; validated bycargo test -q --workspace. - Iteration 74 completed:
confirmed pure cache-only miss behavior for Level-1 lenses with explicit regressions
test_pure_mode_rejects_bounded_lens_with_f803([crates/fct-engine/src/r_dag.rs]) andtest_runner_bounded_lens_in_pure_mode_is_f803([tests/test_runner_tests.rs]); checklist item promoted to done and revalidated bycargo test -q --workspace. - Iteration 75 completed:
validated active support paths for
F402/F405/F454/F455/F456across parser/engine/render/validator with existing deterministic regressions (for example: parsertest_attribute_interpolation_forbidden_f402, enginetest_invalid_variable_path_f405, guard deny/undecidable and effect-declaration tests in [crates/fct-engine/src/r_dag.rs], [crates/fct-engine/src/tool_executor.rs], [crates/fct-render/src/lib.rs]); checklist support item promoted to done and revalidated bycargo test -q --workspace. - Iteration 76 completed:
implemented
fct inspectstructured views with file outputs--ast/--dag/--layout/--policyand mode/budget options in [src/commands/mod.rs], [src/main.rs], [src/commands/inspect.rs]; added testsdag_view_preserves_first_insertion_order_under_overridesandexecute_inspect_writes_requested_views, plus public render helpers for policy view/hash in [crates/fct-render/src/lib.rs]; validated bycargo test -q --workspace. - Iteration 77 completed:
added cross-platform/replay canonical determinism regressions in [
tests/integration_test.rs] (test_integration_crlf_equivalent_canonical_output_deterministic,test_integration_replay_canonical_bytes_and_hash_stable) and promoted canonical snapshot done-gate; validated bycargo test -q --workspace. - Iteration 78 completed:
completed trust-level mode matrix coverage in [
crates/fct-engine/src/r_dag.rs] by adding volatile-path regressionstest_pure_mode_rejects_volatile_lens_with_f801andtest_exec_mode_volatile_lens_default_denied_by_guard_with_f454(complementing existing Level-0/Level-1 tests), and promoted the matrix done-gate; validated bycargo test -q --workspace. - Iteration 79 completed:
promoted
F801disallow-path mapping to done based on deterministic coverage in profile and runtime suites: core-profile rejections in [tests/profile_tests.rs], pure-mode runtime prohibition in [crates/fct-engine/src/r_dag.rs] and [tests/test_runner_tests.rs] (including volatile/bounded paths), all green undercargo test -q --workspace. - Iteration 80 completed:
expanded CLI command integration coverage with new command-level tests in [
src/commands/build.rs] and [src/commands/test.rs] (success/error-mode paths), alongside existingrunartifact andinspectview-output tests in [src/commands/run.rs] and [src/commands/inspect.rs], and promoted CLI done-gate; validated bycargo test -q --workspace. - Iteration 81 completed:
added parser syntax matrix fixtures in [
crates/fct-parser/tests/syntax_matrix_tests.rs] (facet_forms_matrix_parses,pipeline_shapes_matrix_parses) covering standard facet forms and representative pipeline shapes, and promoted the syntax-matrix item to done; validated bycargo test -q --workspace. - Iteration 82 completed:
implemented Appendix C cache-key contract in R-DAG Level-1 lens path: added deterministic cache-key envelope hashing (
lens {name,version}, input, args, named_args, host_profile_id, facet_version), runtime L1 cache store in execution context, pure-mode cache-hit execution (withF803on miss), and exec-mode cache population in [crates/fct-engine/src/r_dag.rs], plus default lensversion()API in [crates/fct-std/src/lib.rs]; added regressionstest_pure_mode_uses_level1_cache_hit,test_level1_cache_key_matches_appendix_c_envelope_and_is_stable, and extended bounded-allow path to assert cache population; validated bycargo test -q -p fct-engineandcargo test -q --workspace. - Iteration 83 completed:
removed non-standard numeric FACET diagnostics from extension paths by namespacing host-only errors: resolver extension errors now emit
X.resolver.*(FILE_TIMEOUT,SENSITIVE_LOCATION,SUSPICIOUS_ENCODING) instead of legacyF603-F606in [crates/fct-resolver/src/lib.rs], validator legacy extension errors now emitX.validator.*(instead ofF402/F404) in [crates/fct-validator/src/errors.rs] with docs aligned in [crates/fct-validator/src/lib.rs]; added regression teststest_extension_errors_use_namespaced_codes(resolver) andextension_diagnostics_are_namespaced(validator); validated bycargo test -q -p fct-resolver,cargo test -q -p fct-validator, andcargo test -q --workspace. - Iteration 84 completed:
added deterministic error-catalog matrix suite in [
tests/error_catalog_matrix_tests.rs] covering parser/validator/engine/resolver paths with one explicit case per supported code path (F001,F002,F003,F402,F401,F405,F451,F452,F453,F454,F455,F456,F505,F601,F602,F801,F802,F803,F901,F902); validated bycargo test -q --test error_catalog_matrix_testsandcargo test -q --workspace. - Iteration 85 completed:
aligned resolver import-sandbox diagnostics with v2.1.3 import catalog: absolute paths, parent traversal, and outside-allowlist (symlink escape) now emit
F601(while non-standard extension checks remainX.resolver.*) in [crates/fct-resolver/src/lib.rs]; added regressiontest_import_sandbox_violations_emit_f601; validated bycargo test -q -p fct-resolverandcargo test -q --workspace. - Iteration 86 completed:
improved Token Box compression path in [
crates/fct-engine/src/box_model.rs] for deterministic deficit reduction and string-content truncation with UTF-8 char-boundary safety, plus strategy output propagation; added regressionstest_utf8_truncation_preserves_char_boundariesandtest_section_drops_when_over_budget_and_at_minin [crates/fct-engine/src/lib.rs]; validated bycargo test -q -p fct-engineandcargo test -q --workspace. - Iteration 87 completed:
aligned Token Box fit-path with §11.3 by removing non-normative growth expansion when total already fits budget in [
crates/fct-engine/src/box_model.rs], and updated baseline allocation expectations intest_basic_allocation_no_compression([crates/fct-engine/src/lib.rs]); validated bycargo test -q -p fct-engineandcargo test -q --workspace. - Iteration 88 completed:
added integration regression for
@varssingleton ordered-map merge across import expansion in [tests/import_validation_tests.rs] (vars_singleton_merge_preserves_first_insertion_order), verifying single merged@varsblock, first-insertion key order stability, and override semantics; validated bycargo test -q --test import_validation_testsandcargo test -q --workspace. - Iteration 89 completed:
finalized Token Box non-string truncation semantics in [
crates/fct-engine/src/box_model.rs] by replacing size-only fallback with deterministic recursive truncation forValueNode::ListandValueNode::Map(tail-first, UTF-8-safe string boundaries preserved, materialized content updates); added regressionstest_non_string_list_truncation_updates_contentandtest_non_string_multimodal_list_truncation_is_materializedin [crates/fct-engine/src/lib.rs], validated bycargo test -q -p fct-engineandcargo test -q --workspace. - Iteration 90 completed:
implemented Appendix D JSON Schema mapping in renderer for primitives, struct/list/map/union, and
embedding<size=N>in [crates/fct-render/src/lib.rs] (type_node_to_json_schema), and added schema regressionstest_type_node_to_json_schema_primitivesandtest_type_node_to_json_schema_struct_list_map_union_embedding; validated bycargo test -q -p fct-renderandcargo test -q --workspace. - Iteration 91 completed:
implemented interface JSON-schema mappability checks in validator (
@interfaceparam/return type validation against Appendix D forms) in [crates/fct-validator/src/checker.rs] viavalidate_interface_type_mappable, with regressionsvalidator_rejects_unmappable_interface_primitive_typeandvalidator_rejects_unmappable_interface_image_typein [tests/interface_tools_tests.rs]; validated bycargo test -q -p fct-validator,cargo test -q --test interface_tools_tests, andcargo test -q --workspace. - Iteration 92 completed:
extended interface type grammar parsing in [
crates/fct-parser/src/parser.rs] from primitive-only to recursive FTS forms for interfaces (struct,list<T>,map<string,T>, unionsT1 | T2,embedding<size=N>,image(...),audio(...), including multilinestructreturn types) and added parser regressionsparses_interface_composite_types,parses_interface_union_and_embedding_types, andparses_interface_multiline_struct_return_type; validated bycargo test -q -p fct-parserandcargo test -q --workspace. - Iteration 93 completed:
finalized Section 3.13 runtime input materialization coverage by adding regression
test_input_default_type_mismatch_returns_f453in [crates/fct-engine/src/r_dag.rs], complementing existing runtime/default/missing/type-mismatch/pipeline-path and variable-path (F401/F405/F452) tests; validated bycargo test -q -p fct-engineandcargo test -q --workspace. - Iteration 94 completed:
finalized canonical renderer schema migration to strict v2.1.3 shape (
metadata/tools/messagesonly) by removing legacy v2.0 fields/usages in [crates/fct-render/src/lib.rs], [src/commands/run.rs], [tests/integration_test.rs], and [tests/interface_tools_tests.rs]; added/updated regression assertions in renderer and integration paths; validated bycargo test -q -p fct-renderandcargo test -q --workspace. - Iteration 95 completed:
promoted Section 3.8 gas/cache contract items to done based on active engine enforcement and deterministic regression coverage: gas exhaustion emits
F902via [crates/fct-engine/src/errors.rs] + [crates/fct-engine/src/r_dag.rs] (test_gas_consumption,matrix_f902_gas_exhausted), and Appendix C Level-1 cache-key contract is implemented in [crates/fct-engine/src/r_dag.rs] (test_level1_cache_key_matches_appendix_c_envelope_and_is_stable,test_pure_mode_uses_level1_cache_hit); validated bycargo test -q -p fct-engine test_gas_consumption,cargo test -q -p fct-engine test_level1_cache_key_matches_appendix_c_envelope_and_is_stable,cargo test -q -p fct-engine test_pure_mode_uses_level1_cache_hit,cargo test -q --test error_catalog_matrix_tests matrix_f902_gas_exhausted, andcargo test -q --workspace. - Iteration 96 completed:
closed remaining Section 3.9 Phase-5 rendering checks: canonical JSON render path is active in runtime pipeline and replay-determinism gate is proven by integration regressions in [
tests/integration_test.rs] (test_integration_render_to_json,test_integration_replay_canonical_bytes_and_hash_stable,test_integration_crlf_equivalent_canonical_output_deterministic); validated by targeted integration test runs andcargo test -q --workspace. - Iteration 97 completed:
completed remaining executable R-DAG core guarantees in [
crates/fct-engine/src/r_dag.rs]: dependency graph construction from@varsvarrefs is active, missing dependency and cycle diagnostics are deterministically emitted (F401/F505), and Phase-3 now freezes computed variable map after execution (ExecutionContext::freeze_variables+ immutableset_variableguard withF452on post-freeze mutation); regressionstest_missing_dependency_returns_f401,test_cycle_detection_returns_f505, andtest_execute_freezes_computed_variable_map; validated by targetedfct-enginetests andcargo test -q --workspace. - Iteration 98 completed:
completed pure-mode lens policy enforcement across active runtime paths: R-DAG continues to enforce
L2 -> F801andL1 cache-only -> F803, and Token Boxstrategypath now enforces Level-0-only in pure mode viaTokenBoxModel::allocate_with_mode/Section::apply_compressionin [crates/fct-engine/src/box_model.rs], wired into main run/test flows in [src/commands/run.rs] and [crates/fct-engine/src/test_runner.rs]; added regressiontest_pure_mode_rejects_non_level0_strategy_lens_with_f801in [crates/fct-engine/src/lib.rs]; validated by targetedfct-enginetests andcargo test -q --workspace. - Iteration 99 completed:
completed Phase-3 policy materialization path:
ExecutionContextnow storeseffective_policyand computedpolicy_hash, with hash computed as JCS envelope over{policy_version, policy}in [crates/fct-engine/src/r_dag.rs], andfct runnow passes this hash into renderer context in [src/commands/run.rs]; added regressionstest_execute_materializes_effective_policy_and_hashandtest_execute_without_policy_sets_policy_hash_to_nonein [crates/fct-engine/src/r_dag.rs]; validated by targetedfct-enginetests andcargo test -q --workspace. - Iteration 100 completed:
implemented Phase-2 lens pipeline step assignability validation (
F451) in [crates/fct-validator/src/checker.rs] viacheck_lens_pipeline_typesand deterministic AST-signature -> validator-type mapping, then added regressionspipeline_step_type_mismatch_returns_f451,pipeline_step_type_assignability_accepts_compatible_chain, andpipeline_uses_variable_type_for_step_assignability(same file); validated bycargo test -q -p fct-validatorandcargo test -q --workspace. - Iteration 101 completed:
enforced layout strategy determinism in Phase-4 compression path by rejecting non-deterministic strategy lenses (
signature.deterministic == false) withF801before execution in [crates/fct-engine/src/box_model.rs], and added regressiontest_exec_mode_rejects_nondeterministic_strategy_lens_with_f801in [crates/fct-engine/src/lib.rs]; validated bycargo test -q -p fct-engine test_exec_mode_rejects_nondeterministic_strategy_lens_with_f801andcargo test -q --workspace. - Iteration 102 completed:
added regex-safety regression for Level-0 string replacement semantics in [
crates/fct-std/src/lib.rs] (test_replace_lens_treats_pattern_as_literal_not_regex) to ensure regex metacharacters are not interpreted as unsafe regex behavior in the purereplacelens path; validated bycargo test -q -p fct-std test_replace_lens_treats_pattern_as_literal_not_regexandcargo test -q --workspace. - Iteration 103 completed:
added AST immutability regression for Phase-3 execution in [
crates/fct-engine/src/r_dag.rs] (test_execute_does_not_mutate_input_ast), proving the resolved AST is unchanged afterRDagEngine::execute; validated bycargo test -q -p fct-engine test_execute_does_not_mutate_input_astandcargo test -q --workspace. - Iteration 104 completed:
completed Phase-4 section materialization from computed runtime values in [
src/commands/run.rs]: messagecontentnow resolves recursive expressions including lens pipelines againstcomputed_varsbefore Token Box allocation (doc_to_sections/resolve_message_value), with strict Level-0-only lens policy for message content and explicitF801/F802paths; added regressionsresolve_message_value_evaluates_pipeline_from_computed_varsandresolve_message_value_rejects_non_pure_lens_in_message_content; validated bycargo test -q resolve_message_value_andcargo test -q --workspace. - Iteration 105 completed:
aligned
@testcanonical-view message resolution withrunby enabling recursive message expression/lens pipeline resolution in [crates/fct-engine/src/test_runner.rs] (resolve_message_value_for_test) using Level-0-only message lenses and deterministicF801/F802behavior, plus integration regressiontest_runner_resolves_pipeline_message_content_in_canonical_viewin [tests/test_runner_tests.rs]; validated bycargo test -q --test test_runner_tests test_runner_resolves_pipeline_message_content_in_canonical_viewandcargo test -q --workspace. - Iteration 106 completed:
wired
fct testinto strict Phase-1/2 preflight by adding import resolution and validator pass before test discovery/execution in [src/commands/test.rs] (parse -> resolve -> validate -> run tests), with regressionexecute_test_validates_document_even_without_tests; validated bycargo test -q execute_test_validates_document_even_without_testsandcargo test -q --workspace. - Iteration 107 completed:
enforced guard-timing evidence for prohibited initiation in runtime guarded paths by adding/strengthening regressions in [
crates/fct-engine/src/tool_executor.rs] (test_tool_call_guard_denied_does_not_invoke_handler,test_tool_call_guard_undecidable_does_not_invoke_handler) and [crates/fct-engine/src/r_dag.rs] (test_exec_mode_guard_denied_bounded_lens_not_executed_before_allow, updatedtest_exec_mode_bounded_lens_policy_undecidable_returns_f455to assert lens non-execution underF455); validated by targetedcargo test -q -p fct-engine ...runs andcargo test -q --workspace. - Iteration 108 completed:
strengthened multimodal message-content validation in [
crates/fct-validator/src/checker.rs] to enforce canonicalassetstructure forimage/audioitems (kind,format,digest{algo=sha256,value},shapewith modality-specific fields), plus added facet-semantics regressions in [tests/facet_semantics_tests.rs] (multimodal_image_asset_canonical_form_is_accepted,multimodal_audio_asset_canonical_form_is_accepted, invalid digest/format cases); validated bycargo test -q --test facet_semantics_tests,cargo test -q -p fct-validator, andcargo test -q --workspace. - Iteration 109 completed:
aligned renderer content-list emission to FACET v2.1.3 canonical item form in [
crates/fct-render/src/lib.rs] by replacing legacy synthetic multimodal wrapping with normative{type,text|asset}item emission (text/image/audio) and strict item-type validation at render stage; added regressiontest_render_preserves_canonical_multimodal_content_itemsand validated withcargo test -q -p fct-renderandcargo test -q --workspace. - Iteration 110 completed:
improved failure-path provenance visibility in [
crates/fct-engine/src/test_runner.rs] so failed tests now still emitexecution_output(guard events) when available, and added regressions in [tests/test_runner_tests.rs] to assert denied/undecidable mockedtool_callfailures preserveexecution.provenance.events[0]withop=tool_callanderror_code=F454/F455; validated by targeted test runs andcargo test -q --workspace. - Iteration 111 completed:
wired effective layout budget selection in
runto prefer@context.budgetwhen present and otherwise use deterministic host budget input, with metadatabudget_unitsaligned to the effective value in [src/commands/run.rs]; added regressionseffective_layout_budget_prefers_context_budgetandeffective_layout_budget_uses_host_budget_when_context_absent; validated by targeted tests andcargo test -q --workspace. - Iteration 112 completed:
aligned runtime section materialization in
runwith message/layout semantics in [src/commands/run.rs]: sections now apply@context.defaultsand per-message overrides forid|priority|min|grow|shrink|strategy, andwhengating is evaluated from both facet attributes and message bodywhen; added regressionsdoc_to_sections_applies_context_defaults_and_message_overridesanddoc_to_sections_applies_body_when_gating; validated by targeted tests andcargo test -q --workspace. - Iteration 113 completed:
aligned
TestRunnerPhase-4 section construction withrunsemantics in [crates/fct-engine/src/test_runner.rs]: effective budget now prefers@context.budget, sections apply@context.defaultsand per-message overrides (id|priority|min|grow|shrink|strategy), section content is resolved from messagecontent, andwhengating now composes attribute+body conditions; added regressionstest_runner_canonical_omits_body_when_false_message_blocksandtest_runner_applies_context_budget_and_defaults_to_layoutin [tests/test_runner_tests.rs]; validated bycargo test -q --test test_runner_testsandcargo test -q --workspace. - Iteration 114 completed:
extended validator FTS string-type support for multimodal declarations in [
crates/fct-validator/src/checker.rs]:parse_type_stringnow recognizesimage,audio, andembedding<size=N>(positiveN), andinfer_typenow resolves@input(type=\"...\")directives to declared FTS types instead of unconditionalany; added semantics regressions in [tests/facet_semantics_tests.rs] (input_allows_multimodal_image_type,input_allows_multimodal_audio_type,input_allows_embedding_type_with_size,input_rejects_embedding_type_with_non_positive_size,var_types_multimodal_matches_input_declared_type); validated bycargo test -q --test facet_semantics_tests,cargo test -q -p fct-validator, andcargo test -q --workspace. - Iteration 115 completed:
implemented
enumconstraint support in validator type declarations and constraint checks: parser/validator now accepts@var_types.{x}.enumas a non-empty atom-literal list and enforces it across scalar runtime values (string/int/float/bool/null) in [crates/fct-validator/src/checker.rs] and [crates/fct-validator/src/constraints.rs]; added regressionstest_f452_constraint_enum_violationandtest_f452_constraint_enum_non_atom_itemin [tests/error_tests.rs]; validated bycargo test -q --test error_tests,cargo test -q -p fct-validator, andcargo test -q --workspace. - Iteration 116 completed:
strengthened FTS primitive/constraint regression coverage in [
tests/facet_semantics_tests.rs] withinput_allows_all_primitive_types,var_types_enum_accepts_matching_string_literal, andvar_types_enum_accepts_matching_int_literal; validated bycargo test -q --test facet_semantics_testsandcargo test -q --workspace. - Iteration 117 completed:
completed validator-side composite FTS type-expression support and direct assignability checks for
@var_types/@inputin [crates/fct-validator/src/checker.rs]: added recursive parser forstruct {..},list<T>,map<string,T>, unions, nested composites, and media constraints syntax, plus recursive value-vs-type validation for struct/list/map/union and typed directive/pipeline paths; added regression coverage in [tests/facet_semantics_tests.rs] (input_allows_composite_list_type,input_allows_composite_map_type,input_allows_composite_struct_type,input_allows_union_type,input_allows_nested_composite_type_expression,var_types_struct_accepts_matching_map_literal,var_types_struct_rejects_missing_required_field,var_types_list_rejects_non_matching_item_type,var_types_map_rejects_non_matching_value_type,var_types_union_accepts_member_value); validated bycargo test -q -p fct-validator,cargo test -q --test facet_semantics_tests, andcargo test -q --workspace. - Iteration 118 completed:
finalized FTS assignability semantics and multimodal constraint assignability in [
crates/fct-validator/src/types.rs] and validator value checking in [crates/fct-validator/src/checker.rs]: primitive assignability is exact (exceptanytarget), struct/list/map/union assignability follows Section 8.4, multimodal assignability checks (image/audio/embedding) now respect format/dimension/duration/size constraints, and validator type checks use these rules for literals and typed@input(...); added regressions in [crates/fct-validator/src/types.rs] (assignability unit tests) and [tests/facet_semantics_tests.rs] (input_allows_image_type_with_constraints,input_rejects_image_type_with_invalid_format,var_types_multimodal_image_constraint_accepts_narrower_input_type,var_types_multimodal_image_constraint_rejects_broader_input_type,var_types_embedding_rejects_wrong_size_vector,var_types_image_constraints_accept_valid_asset_literal,var_types_image_constraints_reject_asset_over_max_dim,primitive_int_is_not_assignable_to_float_type); validated bycargo test -q -p fct-validator,cargo test -q --test facet_semantics_tests, andcargo test -q --workspace. - Iteration 119 completed:
added dedicated FTS conformance matrix suite in [
tests/fts_conformance_matrix_tests.rs] covering positive and negative cases for primitives, constraints (min/max/pattern/enum), composites (struct/list/map/union), multimodal (image/audio/embedding), and invalid type-expression diagnostics (F451/F452expectations); validated bycargo test -q --test fts_conformance_matrix_testsandcargo test -q --workspace. - Iteration 120 completed:
completed lens metadata/gas contract coverage for Section 9 in [
crates/fct-std/src/lib.rs] and [crates/fct-engine/src/r_dag.rs]: added explicitDeterminismClassandLensMetadataprojection (name/version/input/output/trust/determinism), introduced deterministic per-lensgas_cost(...)API onLens, and enforced lens-level gas charging in R-DAG before execution; added regressionstest_registry_metadata_has_version_and_determinism_class,test_registry_metadata_listing_is_sorted_and_populated(fct-std) andtest_lens_gas_cost_is_enforced(fct-engine); validated bycargo test -q -p fct-std,cargo test -q -p fct-engine, andcargo test -q --workspace. - Iteration 121 completed:
reconciled Section 12 canonical-asset/host-profile checklist status with implemented behavior: validator and renderer already enforce/emit canonical multimodal asset form (
kind/format/digest/shape) with regressions in [tests/facet_semantics_tests.rs] and [crates/fct-render/src/lib.rs] (test_render_preserves_canonical_multimodal_content_items), while canonical metadata host profile semantics are covered in run/render tests (host_profile_idrequired/propagated in [src/commands/run.rs] and [crates/fct-render/src/lib.rs]); revalidated withcargo test -q --workspace. - Iteration 122 completed:
reconciled Section 16 validator checklist status:
@policyschema/parser item promoted to done based on active Phase-2 enforcement in [crates/fct-validator/src/checker.rs] and existing dedicated fixture coverage in [tests/policy_validation_tests.rs] (top-level keys, rule schema, canonical naming, matcher rules, condition typing, known-entity cross-checks), with overall verification oncargo test -q --workspace. - Iteration 123 completed:
consolidated duplicate FTS surfaces into one canonical implementation by switching validator type API to re-export
fct-astFTS in [crates/fct-validator/src/types.rs], extending canonical AST FTS compatibility/assignability coverage in [crates/fct-ast/src/types.rs], and removing checker-side wrapper translation by using direct AST FTS in [crates/fct-validator/src/checker.rs] plus updated constraint compatibility in [crates/fct-validator/src/constraints.rs]; validated bycargo test -q -p fct-ast,cargo test -q -p fct-validator, andcargo test -q --workspace. - Iteration 124 completed:
created required conformance fixture directory structure under [
tests/conformance/] with profile buckets [tests/conformance/core], [tests/conformance/hypervisor], [tests/conformance/policy], [tests/conformance/canonical] (each with placeholder README), and added regressionrequired_conformance_fixture_directories_existin [tests/conformance_layout_tests.rs]; validated bycargo test -q --test conformance_layout_testsandcargo test -q --workspace. - Iteration 125 completed:
introduced command-layer module boundaries for
policy,guard,artifact,canonical, andmode_profilein [src/commands/policy.rs], [src/commands/guard.rs], [src/commands/artifact.rs], [src/commands/canonical.rs], [src/commands/mode_profile.rs] with shared wiring from [src/commands/run.rs] and module exports in [src/commands/mod.rs]; added module-level unit regressions (mode resolution, guard sequencing, canonical JSON stability, policy hash-seed fields, artifact hash-chain presence), validated bycargo test -q --workspace. - Iteration 126 completed:
updated CLI/help terminology to FACET v2.1.3 in [
src/commands/mod.rs] (clap command description), [src/main.rs] (entry-point header), and CLI reference wording in [docs/06-cli.md]; validated bycargo test -q --workspace. - Iteration 127 completed:
added explicit replay determinism and legacy-shape guard coverage in [
tests/replay_determinism_tests.rs] (canonical_output_is_stable_across_repeated_runs,canonical_output_has_no_legacy_v20_top_level_fields) and validated repeatedly viacargo test -q --test replay_determinism_testsandcargo test -q --workspace. - Iteration 128 completed:
enabled dedicated CI conformance gate in [
.github/workflows/ci.yml] (conformancejob with parser/validator + fixture/semantics + determinism suites) and extended CI branch triggers to includerustfor remote validation parity; verified local parity withcargo test -q -p fct-parser,cargo test -q -p fct-validator,cargo test -q --test conformance_layout_tests,cargo test -q --test fts_conformance_matrix_tests,cargo test -q --test facet_semantics_tests,cargo test -q --test replay_determinism_tests, pluscargo test -q --workspace. - Iteration 129 completed:
synchronized remaining parser/validator/runtime migration files required for clean CI compilation (including parser normalization exports and conformance matrix suites), then verified remote
Conformance Suites (v2.1.3)job is green on branchrustin CI run23896427463([.github/workflows/ci.yml]); local parity remains green undercargo test -q -p fct-parser,cargo test -q -p fct-validator,cargo test -q --test conformance_layout_tests,cargo test -q --test fts_conformance_matrix_tests,cargo test -q --test facet_semantics_tests,cargo test -q --test replay_determinism_tests, andcargo test -q --workspace. - Iteration 26 completed:
section id derivation moved toward spec form in pipeline builders (
system#n/user#n/assistant#ninrunandtest_runner), and renderer now accepts both legacy ids and role-indexed ids for canonical role mapping.
1) How to Use This Checklist
- Confirm migration target: Core profile only, or full Hypervisor profile. Selected target: full Hypervisor profile (Section 3 complete).
- Confirm delivery plan:
Core-firstis recommended, thenHypervisor completion. Delivery path followed: Core-first milestones A-D, then Hypervisor milestones E-J. - Track each item with evidence: PR link, test file, and fixture ID. Evidence format in this document: per-iteration file refs + explicit test commands.
- Mark item done only when both are true:
implementation merged + conformance tests green.
Enforced with stage-by-stage commits and
cargo test -q --workspacegreen gates.
2) Workstreams
- WS-A: normalization, lexer/parser, AST reshape (baseline).
- WS-B: Phase 1 resolver and deterministic merge (baseline).
- WS-C: Phase 2 validator and full FTS checks.
- WS-D: Phase 3 R-DAG,
@input, lens execution policy. - WS-E: Phase 4 Token Box Model in FACET Units.
- WS-F: Phase 5 canonical JSON + JCS + hashes.
- WS-G: policy, runtime guard, fail-closed behavior.
- WS-H: execution artifact, provenance hash chain, attestation.
- WS-I: CLI parity (
build/run/test/inspect) and fixtures.
3) Spec Compliance Checklist
3.1 Sections 1-2: Scope, Conformance, Profiles, Extensions
- Add constants:
facet_version = "2.1.3"andpolicy_version = "1". - Parse full syntax in all profiles; enforce profile restrictions after parse.
- Map syntactically valid but profile-disallowed constructs to
F801(notF003). - Enforce host diagnostic namespace:
X.<host>.<code>. - Reserve numeric
F000-F999for FACET standard only.
Done when:
- Core profile fixtures reject Hypervisor-only constructs via
F801. - Extension diagnostics never emit non-standard
F###values.
3.2 Section 3: File Normalization
- Validate UTF-8 at ingest (parser byte API).
- Normalize source to NFC before parse.
- Normalize line endings to LF.
- Reject tabs with
F002. - Ensure spans and hashing use normalized source coordinates.
Done when:
- CRLF and LF equivalent inputs produce identical
document_hash. - NFC-equivalent inputs produce identical AST and canonical output.
3.3 Section 4: Lexical Rules
- Enforce identifier grammar:
[A-Za-z_][A-Za-z0-9_]*. - Reject non-ASCII identifiers as
F003. - Support escapes:
\",\\,\n,\t,\r,\uXXXX. - Reject invalid escape or unclosed string as
F003. - Support full scalar grammar:
bool, null, int (with optional
-), float, exponent. - Allow map keys as identifier or quoted string at syntax level.
Done when:
- Lexer fixture suite passes for all positive/negative cases.
3.4 Section 5: Concrete Syntax
- Keep strict 2-space indentation semantics.
- Enforce attribute atom set:
string|number|bool|null|varref. - Reject lens pipelines inside attributes (
F003). - Reject
@input(...)inside attributes (F003). - Reject attribute interpolation `` (
F402). - Support inline list/map literals everywhere allowed.
- Reject trailing commas in inline list/map (
F003). - Parse pipelines and varrefs in all profiles.
- Enforce directive-expression placement rules for
@input(...).
Done when:
- Syntax fixture matrix covers every facet form and pipeline shape.
3.5 Section 6: AST Model
- Replace unordered semantic maps with ordered representation.
- Add/align required nodes:
Added/aliased normative AST node forms in [
crates/fct-ast/src/lib.rs] (MapNode,ListNode,VarRefNode,LensPipelineNode,InputExprNode,ImportDirectiveNode) while keeping existing runtime-compatible node layout; typed key kinds are represented byMapKeyKind. Regression checks:var_ref_node_parses_dotted_reference,var_ref_node_parses_single_name_reference,map_node_preserves_insertion_order. - Add explicit
@policyAST handling while preserving order. - Preserve normalized span coordinates.
Done when:
- AST snapshot tests are deterministic across runs/platforms.
3.6 Section 7: Resolution and Merge
- Resolve imports relative to importing file.
- Enforce import sandbox:
allowlisted roots, no absolute paths, no
.., no URLs. - Emit sandbox/import lookup failures as
F601. - Emit import cycles as
F602. - Expand imports in source encounter order.
- Enforce standard facet cardinality rules.
- Implement singleton-map deep merge with first-insertion key position retained.
- Implement repeatable-block concatenation in encounter order.
- Implement keyed-list merge where enabled.
- Implement
@policylist merge rules forallowanddeny. - Output both Resolved Source Form and Resolved AST.
Done when:
- Merge fixtures prove key position stability under override.
@policymerge fixtures proveidkeyed behavior and append behavior.
3.7 Section 8: FTS
- Consolidate current duplicate type systems into one normative FTS.
Validator FTS API now re-exports canonical AST types (single source of truth) in [
crates/fct-validator/src/types.rs], with checker conversion collapsed to direct AST FTS usage in [crates/fct-validator/src/checker.rs] and shared assignability semantics in [crates/fct-ast/src/types.rs]. - Support primitives:
string int float bool null any. - Support constraints:
min max pattern enum. - Support composites:
struct list<T> map<string,T> union. - Support multimodal types:
image,audio,embedding<size=N>. - Implement assignability exactly per Section 8.4.
- Emit
F451for type mismatch andF452for constraint violations.
Done when:
- Assignability and constraints conformance matrix is green.
3.8 Section 9: Lens Registry, Trust, Gas, Determinism
- Extend lens metadata: name, version, input/output FTS types, trust level, gas function, determinism class.
- Require
effect_classfor trust levels 1 and 2. Enforced for runtime guarded trust levels with validation on first use in R-DAG. - Emit
F456for missing/invalideffect_class. Implemented in runtime lens execution path with dedicated guard tests. - Emit
F802for unknown lens. - Phase 2 pipeline typing must validate step assignability (
F451). Implemented in validator pipeline pass (check_lens_pipeline_types) with regression tests in [crates/fct-validator/src/checker.rs]. - Enforce gas limit and emit
F902. - Enforce pure mode:
L2 forbidden (
F801), L1 cache-only (F803on miss), L0 allowed. - Implement Appendix C cache-key contract.
- Enforce layout strategy determinism requirements.
Strategy compression now rejects non-deterministic lenses before execution in [
crates/fct-engine/src/box_model.rs], with regression coverage in [crates/fct-engine/src/lib.rs]. - Ensure regex safety for Level-0 claims (RE2-class or proven-safe subset).
Added regression on literal/non-regex
replacebehavior for Level-0 lens safety in [crates/fct-std/src/lib.rs].
Done when:
- Mode x trust-level matrix tests are green.
- Pure cache-only miss path reliably emits
F803.
3.9 Section 10: Execution Model (Phases 1-5)
- Wire strict phase pipeline into
build,run, andtest. - Treat AST immutable after successful Phase 2.
Phase-3 execution now has explicit regression evidence that input AST remains unchanged (
test_execute_does_not_mutate_input_astin [crates/fct-engine/src/r_dag.rs]). - Build R-DAG from
$vardependencies in@vars. - Emit
F401for unknown var in compute andF505for cycles. - Tie-break independent nodes by merged ordered-map insertion order.
- Ensure override does not change variable canonical position.
- Freeze computed variable map.
- Materialize Effective Policy and compute
policy_hash. - Feed Phase 4 with computed messages + context.
CLI
runnow resolves recursive message expressions (including pipelines) against computed variables before section allocation, with deterministic Level-0-only message-lens execution in [src/commands/run.rs]. - Render canonical JSON in Phase 5.
Done when:
- Full replay test proves byte-identical canonical output under identical config.
3.10 Section 11: Token Box Model
- Use FACET Units: UTF-8 byte length of normalized string.
- Build one section per message block.
- Derive deterministic section IDs
<role>#<n>when missing. - Enforce canonical message order preservation.
- Implement deterministic packing algorithm exactly: critical load check, stable flex ordering, strategy, truncation, drop.
- Ensure UTF-8-safe truncation boundaries.
- Emit
F901on critical overflow.
Done when:
- Token-box fixtures pass, including UTF-8 truncation safety cases.
3.11 Section 12: Standard Facets and Semantics
- Enforce
@metavalues as atoms only. - Permit string keys only in
@meta. Implemented via explicit map-key kind tracking (IdentifiervsString) in AST/parser and Phase-2 validation checks outside@metain [crates/fct-ast/src/lib.rs], [crates/fct-parser/src/parser.rs], [crates/fct-validator/src/checker.rs]. - Emit
F452for string keys outside@meta. Enforced in validator (String-keyed maps are only allowed in @meta) with regression coverage for quoted identifier-like keys in [tests/facet_semantics_tests.rs] (quoted_identifier_key_outside_meta_is_rejected,meta_allows_quoted_identifier_like_key); validated bycargo test -q --test facet_semantics_testsandcargo test -q --workspace. - Reject control characters in
@metastring keys. - Validate
@contextminimal schema and defaults. - Ensure deterministic host-provided budget when
@contextabsent.runnow computes effective layout budget deterministically as@context.budget(if present) else host budget input, and surfaces the effective value in canonical metadatabudget_units. - Validate message facet schema:
map body, required
content, allowed layout fields, validwhen. - Emit
F451on non-booleanwhen. - Resolve
@system.toolsas interface references. - Support canonical content forms and multimodal item schema.
Validator now enforces canonical multimodal
assetcontracts forimage/audiocontent items (kind/format/digest/shape), and renderer emits list content in canonical FACET item form{type,text|asset}. - Add canonical asset representation and host profile stability semantics.
Canonical asset shape is validated/emitted in validator/render paths;
host_profile_idis propagated in canonical metadata and covered by run/render regression tests. Partial: canonical asset structure is validated/emitted; explicit host-profile semantic-digest governance (versioned host canonicalization contract changes) still needs conformance fixtures/documented invariants.
Done when:
- Facet semantics fixture suite is green.
3.12 Section 13: Interfaces
- Parse full interface grammar including function-level
effect. - Enforce unique interface names in resolved AST.
- Enforce unique function names within interface.
- Enforce unique parameter names within function.
- Require valid
effecton each function (F456). - Validate JSON Schema mappability per Appendix D.
- Emit
F452for unknown interface refs in@system.tools.
Done when:
- Interface parser and validator conformance fixtures pass.
3.13 Section 14: Vars, Var Types, Input
- Enforce
@varsas singleton ordered map. - Core profile:
allow literals only in
@vars; reject others withF801. - Enforce
@input(...)placement: only base expr of@varsvalue, optional pipeline tail. - Reject nested
@input(...)in composite literals (F452). - Require
typeattr in@input(...). - Restrict
defaultto atom values. - Runtime input materialization:
defaulting, required-input enforcement, type checks (
F453). Implemented for current@input(type=\"...\")runtime type support in R-DAG and wired into CLIrun --runtime-inputand TestRunner@test input; unified FTS typing now uses the single canonical AST type system (Section 3.7 closed). - Path traversal semantics:
missing var ->
F401, missing field ->F405, numeric index unsupported ->F452unless namespaced extension.
Done when:
- Input/runtime/path fixtures cover all valid and invalid branches.
3.14 Section 15: Testing (@test)
- Align
@testgrammar:vars,input,mock,assert. - Ensure isolated runtime environment per test case.
- Apply
varsoverrides with type checks.@test.varsnow materializes as an appended override@varsblock (deterministic merge semantics preserved), validates against declared@var_types(F451for type mismatch,F452for invalid constraints), and recomputes dependent variables. - Apply
inputoverrides to@inputvalues. - Support mock interception by fully-qualified tool function name.
- Evaluate assertions over
canonical,telemetry, andexecution(recommended). - In pure mode, enforce
F803/F801behavior for prohibited operations. - Enforce policy/guard failures as
F454orF455.
Done when:
@testconformance fixtures pass for mode/policy interactions.
3.15 Section 16: Policy, Capability Classes, Runtime Guard
- Add full
@policyschema parser/validator. Phase-2 validator enforces top-level schema,PolicyRulefield contracts, op enums, canonical-name constraints, matcher syntax, condition typing, and known-name cross-checks fortool_*/lens_call/message_emitwith dedicated conformance tests in [tests/policy_validation_tests.rs]. - Enforce known top-level keys only:
defaults,deny,allow. - Enforce
PolicyRuleschema and field validation. - Implement list merge semantics for
allowanddeny. - Implement canonical identifier normalization for names.
Enforced in Phase-2 for
tool_*,lens_call, andmessage_emitwith canonical-form checks plus cross-check against known interfaces/functions, lenses, and effective message ids. - Enforce conjunctive field matching semantics.
Enforced across guard evaluators for
tool_expose,message_emit,tool_call, andlens_call(op+name+effect+when+unlessall must match; missing/null effect fails matcher wheneffectis required). - Implement
PolicyCondtyping and short-circuit behavior. Phase-2 typing checks are active (F401/F405/F451/F452), and runtime short-circuit semantics (not/all/any) are implemented for all active guard evaluators. - Implement standard operation kinds:
tool_expose,tool_call,lens_call,message_emit. - Build
OpDescwith required fields. Guard evaluators now build/emit operation descriptors with required runtime fields (op, canonicalname,effect_class,mode, decision metadata) acrosstool_expose/message_emit([crates/fct-render/src/lib.rs]),lens_call([crates/fct-engine/src/r_dag.rs]), andtool_call([crates/fct-engine/src/tool_executor.rs],TestRunnere2e in [tests/test_runner_tests.rs]). - Implement effect-class semantics and effect matching.
Effect class matching is enforced conjunctively for
tool_expose/tool_call/lens_call; interface/lens effect declarations feed guard evaluation andF456paths; verified by policy and guard regressions in [tests/policy_validation_tests.rs], [crates/fct-engine/src/tool_executor.rs], [crates/fct-engine/src/r_dag.rs], [crates/fct-render/src/lib.rs]. - Implement runtime guard with fail-closed behavior.
Guard deny/undecidable behavior is active for guarded operations with explicit
F454/F455outcomes;tool_callin@testruntime now also records a denied guard event inpuremode before returningF801(fail-closed evidence path) in [crates/fct-engine/src/test_runner.rs] with e2e assertions in [tests/test_runner_tests.rs]. - Enforce guard timing before prohibited initiation.
Guard checks are now explicitly regression-covered to occur before guarded operation execution (
tool_callhandler non-invocation onF454/F455,lens_callnon-execution onF454/F455) in [crates/fct-engine/src/tool_executor.rs] and [crates/fct-engine/src/r_dag.rs]. - Implement decision algorithm and deterministic defaults.
Deny-first/allow-next/defaults evaluation is implemented across operation guards, including
tool_calldefaults inToolExecutorand renderer/engine guard paths; validated bytool_call/policy regression suites (cargo test -q -p fct-engine test_tool_call_guard_,cargo test -q --test policy_validation_tests). - Emit
F454for deterministic deny. Covered in guarded operation paths (tool_expose,message_emit,lens_call,tool_call) with explicit regressions in [crates/fct-render/src/lib.rs], [crates/fct-engine/src/r_dag.rs], [crates/fct-engine/src/tool_executor.rs], plus matrix coverage in [tests/error_catalog_matrix_tests.rs]. - Emit
F455for undecidable guard evaluation. Covered in guarded operation paths (tool_expose,message_emit,lens_call,tool_call) with explicit regressions and short-circuit fixtures in [crates/fct-render/src/lib.rs], [crates/fct-engine/src/r_dag.rs], [crates/fct-engine/src/tool_executor.rs], and [tests/test_runner_tests.rs]. - Record guard decision events for all guarded attempts.
Event emission is active for guarded attempts in renderer (
tool_expose/message_emit), R-DAG (lens_call), and@testtool execution (tool_call), including deny/undecidable/pure-mode-prohibited attempts with preserved provenance inexecution_output; covered by [tests/test_runner_tests.rs] and artifact/guard tests in [src/commands/run.rs].
Done when:
- Policy conformance suite passes:
canonical names, AND matching, short-circuit, F454/F455 split (validated by
cargo test -q --test policy_validation_tests,cargo test -q --test test_runner_tests, andcargo test -q -p fct-engine test_tool_call_guard_).
3.16 Section 17: Security Model
- Keep Phases 1-2 hermetic:
compile path remains parse+resolve+validate only, with filesystem constrained by import allowlist/sandbox (
F601) in resolver/build path; command-level sandbox regression added in [src/commands/build.rs] (execute_build_rejects_import_outside_allowed_root_with_f601). - Restrict runtime I/O to
@inputand registered L1/L2 lenses. Runtime path enforces operation boundaries: message-content lenses are Level-0-only (F801on non-pure lens), and external/bounded behavior is guarded in R-DAG/test paths; validated by [src/commands/run.rs] and [tests/test_runner_tests.rs]. - Emit
F801for prohibited runtime I/O. Verified in command/runtime tests including message-content non-Level-0 rejection in [src/commands/run.rs] (execute_run_rejects_non_level0_message_lens_with_f801) and pure-mode mockedtool_callprohibition in [tests/test_runner_tests.rs]. - Emit
F455if guarded operation executes without guard decision. Fail-closed guarded-operation behavior is enforced and regression-covered via undecidable guard outcomes (F455) in engine/test/run paths, including command-level lens-guard undecidable case in [src/commands/run.rs] (execute_run_fails_closed_with_f455_for_undecidable_lens_guard).
Done when:
- Security boundary tests pass for compile and runtime.
Validated by targeted command-level regressions plus full workspace run:
cargo test -q execute_build_rejects_import_outside_allowed_root_with_f601,cargo test -q execute_run_,cargo test -q --workspace.
3.17 Section 18: Canonical JSON, Canonicalization, Hashes
- Replace v2.0 render schema with v2.1.3 canonical schema.
- Emit required metadata fields:
facet_version,profile,mode,host_profile_id,document_hash,policy_hash,policy_version,budget_units,target_provider_id. - Emit tools in resolved interface order.
- Emit messages in canonical role order.
- Apply
tool_exposepolicy filtering before emission (Hypervisor MUST). - Serialize canonical JSON with RFC 8785 JCS (or proven equivalent).
- Compute
document_hashfrom Resolved Source Form bytes. - Compute
policy_hashfrom JCS of{policy_version, policy}envelope.
Done when:
- Cross-platform snapshot tests produce identical canonical bytes and hashes.
3.18 Section 19: Error Catalog
- Align parser/validator/engine error mapping to v2.1.3 catalog.
- Remove legacy error semantics that conflict with new catalog.
- Ensure profile/mode disallow paths map to
F801. - Add support for:
F402,F405,F454,F455,F456.
Done when:
- Error matrix fixture set has at least one deterministic case per code path.
3.19 Section 20: CLI (fct)
fct build: implement Phases 1-2 for selected profile/mode.fct run: implement full Phases 1-5 with--pure|--exec. End-to-end run pipeline is active with mode flags, deterministic resolve+validate+R-DAG+layout+render flow, execution artifact emission, and mode/guard boundary regressions in [src/commands/run.rs] (execute_run_writes_execution_json_artifact,execute_run_fails_closed_with_f455_for_undecidable_lens_guard,execute_run_rejects_non_level0_message_lens_with_f801,execute_run_pure_mode_rejects_bounded_lens_with_f803).fct test: execute@testwith policy/guard/mode semantics. CLI test flow performs parse+resolve+validate preflight and runs@testvia guarded TestRunner semantics (policy deny/undecidable, pure-mode prohibitions, canonical/execution assertion targets); command-level regression added in [src/commands/test.rs] (execute_test_runs_guarded_mock_in_exec_mode) plus extensive guard/mode matrix in [tests/test_runner_tests.rs].fct inspect: emit AST/DAG/layout/policy views.- Emit
execution.json(when produced) per Appendix F.
Done when:
- CLI integration tests pass for output, exit codes, and artifact files.
3.20 Appendix C: Cache Key and Pure Cache-Only Contract
- Implement normative L1 cache key envelope and hashing.
- Include required fields: lens name/version, input, args, named_args, host_profile_id, facet_version.
- Ensure pure mode L1 execution is cache-hit only.
Done when:
- Cache-key compatibility fixtures pass across repeated runs.
3.21 Appendix D: FTS -> JSON Schema Mapping
- Implement primitive mappings.
- Implement struct/list/map/union mappings.
- Implement embedding mapping with fixed size.
- Validate optional fields via union with null.
Done when:
- JSON Schema snapshot fixtures pass for all type forms.
3.22 Appendix F: Execution Artifact and Provenance
- Implement artifact metadata schema.
- Include
policy_versionin artifact metadata. - Implement GuardDecision event schema and sequence rules.
- Implement per-operation
input_hash. - Implement hash chain with required
H0seed fields: facet_version, host_profile_id, document_hash, policy_hash, policy_version, profile, mode. - Implement optional attestation envelope validation/serialization.
Done when:
- Artifact verifier tests pass for replay and hash chain integrity.
4) Delivery Plan
4.1 Core-First Milestone (Recommended)
- Milestone A: normalization, parser, AST ordering model.
- Milestone B: resolver, deterministic merge, document hash.
- Milestone C: Core validator, profile restriction logic, canonical metadata.
- Milestone D:
CLI
build/run/inspectfor Core + fixtures. - Release Gate: Appendix E Core requirements green.
4.2 Hypervisor Completion Milestone
- Milestone E: full FTS and interface schema support.
- Milestone F:
deterministic R-DAG +
@inputruntime semantics. - Milestone G: lens trust/effect/gas/cache policy.
- Milestone H: full policy DSL and runtime guard.
- Milestone I: Token Box FACET Units + multimodal canonicalization.
- Milestone J: execution artifact and attestation.
- Release Gate: Appendix E Hypervisor requirements green.
5) Test Matrix
- Parser conformance fixtures: valid corpus and invalid corpus by error code.
- Merge determinism fixtures: imports, singleton overrides, keyed lists.
- Mode/profile fixtures: core/hypervisor x pure/exec matrix.
- Policy fixtures: match order, defaults, effect matching, short-circuit logic.
- Canonical JSON fixtures: tool order, message order, stable hashes, JCS bytes.
- Guard/provenance fixtures:
decision sequence,
input_hash, hash chain head.
6) Risk Register
- Risk:
AST and map-ordering refactor can break all crates.
Mitigation:
add temporary compatibility adapters and migrate crate-by-crate.
Mitigation status: completed via ordered-map rollout and compatibility aliases (
MapKeyKind, AST alias nodes, unified FTS surface), with full workspace regression gate. - Risk:
nondeterminism leaks via map iteration and timestamps.
Mitigation:
ban unordered iteration in canonical paths and remove runtime timestamps from canonical outputs.
Mitigation status: deterministic ordering/canonicalization tests are active (
integration_testreplay + canonical matrix + replay_determinism suite). - Risk:
policy and guard semantics drift from spec.
Mitigation:
write section-16 normative fixtures before implementation.
Mitigation status: section-16 fixtures and guard regressions are active in
tests/policy_validation_tests.rsandtests/test_runner_tests.rs. - Risk: canonicalization mismatch across platforms. Mitigation: add JCS golden vectors and cross-platform CI comparisons. Mitigation status: JCS canonicalization is enforced in renderer/run paths and CI matrix covers linux/macos/windows test runs.
7) Exit Criteria
- Appendix E checklist is fully green for the shipped profile.
- Conformance fixture suites are green in CI.
- Determinism replay tests are stable across repeated runs.
- CLI docs and help text updated to v2.1.3 terminology.
- No legacy v2.0-only behavior leaks into selected v2.1.3 mode/profile.
8) Repository-Specific Task Notes
- Replace
HashMapin AST and semantic merge paths with ordered map type. - Remove TODO stubs in command handlers:
src/commands/build.rs,src/commands/run.rs. - Implement missing validator phases:
validate_interfaces,validate_bodies. - Replace renderer schema with v2.1.3 canonical schema.
- Add module boundaries:
policy,guard,artifact,canonical,mode_profile. - Add fixture directories:
tests/conformance/core,tests/conformance/hypervisor,tests/conformance/policy,tests/conformance/canonical.