@vaudience/aigentflow-flow-validator 0.19.0 → 0.21.0

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.
package/PARITY.md CHANGED
@@ -4,8 +4,85 @@ This document maps every rule in this JavaScript validator back to the AIgentFlo
4
4
  Go reference implementation, records the intentional divergences, and defines the
5
5
  discipline for keeping the two in sync.
6
6
 
7
- **Tracks AIgentFlow flow schema: `v2.820.0`** (`SPEC_VERSION` in [`src/spec/aigentflow-spec.json`](./src/spec/aigentflow-spec.json)), which adds `orchestrator.region` / `orchestrator.enforce_region` (package 0.19.0, below). Earlier: the AigentChat executor was removed (package 0.18.0). Earlier additions: the `examples:` block (package 0.17.0), `server_owned_query_key` (package 0.15.1) from the AIgentFlow release after v2.790.0, `credential_endpoint_unpaired` (package 0.15.2) from AIgentFlow v2.793.0 and the release after it, and `display_name_too_long` (package 0.15.3) from AIgentFlow v2.802.0.
8
-
7
+ **Tracks AIgentFlow flow schema: `v2.827.0`** (`SPEC_VERSION` in [`src/spec/aigentflow-spec.json`](./src/spec/aigentflow-spec.json)), which adds the `here` executor scheme, the `strict_templates` flow key and the rule `template_default_piped` (package 0.21.0, below). Earlier: the warning `compliance_residency_unenforced` (package 0.20.0). `orchestrator.region` / `orchestrator.enforce_region` (package 0.19.0). Earlier: the AigentChat executor was removed (package 0.18.0). Earlier additions: the `examples:` block (package 0.17.0), `server_owned_query_key` (package 0.15.1) from the AIgentFlow release after v2.790.0, `credential_endpoint_unpaired` (package 0.15.2) from AIgentFlow v2.793.0 and the release after it, and `display_name_too_long` (package 0.15.3) from AIgentFlow v2.802.0.
8
+
9
+ > package 0.21.0 — **`here://`, `strict_templates` and `template_default_piped`**, in step
10
+ > with the reference (AIgentFlow v2.827.0; `specVersion` 2.827.0). Three changes.
11
+ >
12
+ > 1. **The `here` executor scheme** (`here://maps/{geocode|reverse_geocode|route|places}`) is
13
+ > added to `executorSchemes`, between `getmd` and `homeassistant`; a `here://` step no longer
14
+ > draws `unknown_executor_scheme`. Fixture `valid-executor-here.yaml` forbids that code.
15
+ > 2. **`strict_templates`**, a new optional top-level boolean, is a known key (`knownKeys.Flow`).
16
+ > A value that is not a boolean is `invalid_type` (field `strict_templates`). A YAML null and
17
+ > the YAML 1.1 words the reference's decoder still reads into a `bool` (`yes`/`no`/`on`/`off`,
18
+ > `y`/`n`, in the usual cases) are accepted; this port cannot tell a quoted scalar from a plain
19
+ > one, so a quoted `"yes"` passes here (looser). Its run-time effect is engine behaviour and out
20
+ > of scope. Fixtures: `valid-strict-templates.yaml`, `invalid-strict-templates-type.yaml`.
21
+ > 3. **`template_default_piped`.** The template function `default` takes the value FIRST
22
+ > (`default .x "fallback"`). A pipeline that passes a value into it as a **non-first command**
23
+ > (`{{ .x | default "w" }}`, mid-chain, parenthesised, inside `if`/`else if`/`range`/`with`/
24
+ > `template`/`block`/`define`, or after a `$v :=` declaration) hands the piped value as the
25
+ > LAST argument, so the fallback is always the result and nothing fails at run time. An
26
+ > **error** at the top level and a **warning** inside a loop body (positional, exactly like
27
+ > `template_syntax_error`; the code survives the demotion), reported at the field of the
28
+ > template with its pipeline in the message. The rule runs only on a template that raised no
29
+ > syntax or function finding, because the reference walks a parse tree that exists only for a
30
+ > template that parses. Message and suggestion are the reference's text (spec section
31
+ > `templateDefaultPiped`). Never flagged: a field (`.query.default`), a variable (`$default`),
32
+ > a string or raw-string literal containing the word, a comment, `default` as the FIRST
33
+ > command (`default .x "w"`, `default (.x | upper) "w"`). The reference's run door tolerates
34
+ > this code (it only refuses a run for other errors); this port has no run door. Fixtures:
35
+ > `invalid-template-default-piped.yaml`, `warn-template-default-piped-loop.yaml`,
36
+ > `valid-template-default-clean.yaml` (forbids the code in both severities: its whole risk is
37
+ > a false positive). The all-correct `valid-minimal.yaml` was rewritten from
38
+ > `{{ .query.name | default "world" }}` to `{{ default .query.name "world" }}`.
39
+ >
40
+ > **Known limits.** There is no Go parse tree here: `src/template/gotmpl-default.ts` is a small
41
+ > tokenizer over each `{{ ... }}` action (string, raw-string and character literals and
42
+ > comments respected; pipelines split on top-level `|`; parentheses recursed). Consequences:
43
+ > (a) the printed pipeline is rebuilt from tokens (whitespace normalised) and matches Go's
44
+ > printing for ordinary pipelines, but may differ in spelling for exotic ones (numeric
45
+ > literals are echoed as written); (b) a `default` reached as a method or chain (`(.x).default`) is not a function call and is not flagged; (c) only the
46
+ > template fields the existing syntax check already walks are covered; (d) the same pipeline
47
+ > text appearing twice in one template is reported once, as in the reference.
48
+
49
+ > package 0.20.0 — **`compliance_residency_unenforced`**, in step with the reference
50
+ > (AIgentFlow v2.821.0; `specVersion` 2.821.0). A **warning**, never an error, and it
51
+ > needs no catalogue. `compliance.residency` is, in the reference, a check against the
52
+ > model catalogue's declared deployments: it says a (provider, model) pair is _eligible_,
53
+ > not which host a call dials. The new rule is the catalogue-free counterpart. When the
54
+ > residency is non-empty and **every** code (trimmed, upper-cased) is `EU`, `DE`, `FR`,
55
+ > `IE`, `NL`, `IT` or `ES` (so `["EU","US"]` is not EU-only), each top-level step and
56
+ > loop sub-step whose executor starts `ai://`, then the orchestrator, warns when its
57
+ > provider is a **region-lane provider** (the providers whose adapter routes on `region`:
58
+ > `bedrock`, `google`, `azure`, `openai`, `assemblyai`, `speechmatics`, `deepgram`,
59
+ > `mistral`; spec key `complianceResidency.regionLaneProviders`) and nothing pins the
60
+ > call. Pinned means: `region` a non-empty string; or `enforce_region` true (a step
61
+ > query: a bool, or the strings `true`/`1`/`yes`; the orchestrator: a bool); or the
62
+ > author named the host (`<provider>_base_url` in the step query, or
63
+ > `executor_config.<provider>.base_url`). The provider is the literal segment of
64
+ > `ai://<provider>/<operation>`, lower-cased for the lane test and printed as written; an
65
+ > empty, slash-less or templated one is skipped, as are providers with no region lane
66
+ > (anthropic native, scaleway, vaiembed) and `exons://` / `aiv://` steps. The
67
+ > orchestrator's provider is `execution.provider` of its `.exons` frontmatter, read by the
68
+ > same light frontmatter reader the save-door rules use; a document that reader cannot
69
+ > read the way the engine would is skipped. Finding: code `compliance_residency_unenforced`,
70
+ > severity warning, field `steps.<id>.executor`, `steps.<id>.loop.steps.<sub-step id>.executor`
71
+ > or `orchestrator.exons`, `stepId` the top-level step (absent for the orchestrator); the
72
+ > message and suggestion are the reference's text (spec keys `messageFormat`,
73
+ > `suggestion`). Order: steps by id, each followed by its loop sub-steps, then the
74
+ > orchestrator. A run-level `region` input is invisible to a static check, so write
75
+ > `region: "{{ .query.region }}"` on the step to state it. **Not ported:** the reference's
76
+ > catalogue check itself (`compliance_violation`, `compliance_unknown_deployment`,
77
+ > `compliance_dynamic_skipped`, and its widening to loop bodies, `quality_gate` judges and
78
+ > the orchestrator's model) — it needs the model catalogue, which this package has never
79
+ > carried (divergence #6). New conformance fixtures:
80
+ > `warn-compliance-residency-unenforced.yaml`, `warn-compliance-residency-unenforced-loop.yaml`,
81
+ > `valid-compliance-residency-pinned.yaml`, `valid-compliance-residency-silent-providers.yaml`
82
+ > (the two `valid-` ones forbid the warning code: their whole risk is a false positive).
83
+ > The mixed-residency, blank-region and `enforce_region` spelling matrix lives in
84
+ > `test/v0200-compliance-residency.test.ts`.
85
+ >
9
86
  > package 0.19.0 — **`orchestrator.region` and `orchestrator.enforce_region`**, in step
10
87
  > with the reference (AIgentFlow v2.820.0; `specVersion` 2.820.0). Both are new keys of
11
88
  > the `orchestrator:` block (a `string` and a `bool`), added to the known-key table.
@@ -984,39 +1061,41 @@ Comparison contract: **error `code` + `valid` verdict**, not message wording. Th
984
1061
 
985
1062
  ## Rule map
986
1063
 
987
- | Area | Go source | JS module | Tested by |
988
- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- |
989
- | Required fields, start-step existence, per-step executor, reserved `.` in IDs, reserved id `orchestrator` | `validateBasicStructure`, `ValidateFlow` head | `validators/basicStructure.ts` | `validate.test.ts`, `conformance.test.ts` |
990
- | Executor URI shape (the ONE parser) + scheme | `ValidateFlow` executor-URL rule (parser.go), `ParseExecutorURLString` | `validators/executors.ts` | `validate.test.ts` |
991
- | Query/property/array-item schema + array constraints | `validateQueryParameters`, `validateProperties`, `validateArrayItems`, `validateArrayConstraints` | `validators/querySchema.ts` | `validate.test.ts` |
992
- | Response-expectation types + array items + `required` | `ValidateFlow` (response block), `validateSemantics` | `validators/responseExpectation.ts` | `validate.test.ts` |
993
- | Response expectation nothing reads (`response_expectation_unread`, warning) | `validateResponseExpectationIsRead` (validation.go) | `validators/responseExpectation.ts` | `validate.test.ts`, `conformance.test.ts` |
994
- | Error strategy (action, goto, max_delay, backoff, retry_on) | `validateErrorStrategy` | `validators/errorStrategy.ts` | `validate.test.ts` |
995
- | Retired `budget:` / `max_retries:` (flow, step, loop sub-step) and `campaign.budget_max_per_child` → `unknown_yaml_key` | `retiredGrammarKeys` + `KnownFields(true)` (parser.go) | `validators/retiredKeys.ts` | `validate.test.ts`, `conformance.test.ts` |
996
- | `next` references (save-door sentinels `null`/`orchestrator`), reachability and cycles (`end` is an ordinary step) | `validateNextLogic` (parser.go), `findReachableSteps`, `checkForCycles` | `validators/connectivity.ts` | `validate.test.ts`, `conformance.test.ts` |
997
- | Unknown keys at every level (`unknown_yaml_key`) and value kinds (`invalid_type`) | `KnownFields(true)` over the reference's types (parser.go); `knownKeys` in the spec | `validators/unknownKeys.ts` | `validate.test.ts`, `conformance.test.ts` |
998
- | `next.parallel` + orchestrator-next requirement | `validateNextLogic`, `validateOrchestratorNext` | `validators/nextLogic.ts` | `validate.test.ts` |
999
- | Expression functions (XOR package/function) | `validateExpressionFunctions` | `validators/expressionFunctions.ts` | `validate.test.ts` |
1000
- | Expression-function catalog (`package:` refused, unknown `function:` refused) | `validateExpressionFunctionCatalog` (parser.go) | `validators/expressionFunctions.ts` | `validate.test.ts`, `conformance.test.ts` |
1001
- | Expression-function USE (`{{ fn_* }}` must be in the catalog AND declared) | `validateExpressionFunctionUsage` (parser.go) | `validators/expressionFunctions.ts` | `validate.test.ts`, `conformance.test.ts` |
1002
- | Loop / for_each / throttle | `validateLoop`, `validateForEach`, `validateThrottle` | `validators/loopForEachThrottle.ts` | `validate.test.ts` |
1003
- | Loop sub-step id that shadows a loop-result summary field (`loop_sub_step_id_reserved`, warning) | `validateLoopSubStepIDCollision` (validation.loopbody.go) | `validators/loopForEachThrottle.ts` | `validate.test.ts`, `conformance.test.ts` |
1004
- | Loop sub-step `next:` targets (same-loop only, sentinels, no parallel) | `validateLoopSubStepNext` (parser.go) | `validators/loopForEachThrottle.ts` | `validate.test.ts`, `conformance.test.ts` |
1005
- | Orchestrator structure + campaign requires orchestrator | `validateOrchestrator`, `validateAndNormalizeCampaign` | `validators/orchestratorCampaign.ts` | `validate.test.ts` |
1006
- | Campaign `max_credits_per_child` (decoded as int64, >= 0), `child_flows` | `CampaignConfig.Validate` (domain.campaign.go) | `validators/orchestratorCampaign.ts` | `validate.test.ts`, `conformance.test.ts` |
1007
- | `tool_discovery` vocabulary, mock scenario `delay`, empty `output:` entry | `validateToolDiscoveryVocabulary`, `validateMockScenarioDelays`, `validateOutputParameters` (parser.go) | `validators/saveDoor.ts` | `validate.test.ts`, `conformance.test.ts` |
1008
- | `executor_config` `${NAME}` references outside the key's scope (`executor_config_env_scope`) | `ValidateExecutorConfigEnvScopes` (parser.go) | `validators/executorConfigEnv.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
1009
- | A step or loop sub-step `query:` declaring a server-owned key (`server_owned_query_key`) | `validateNoServerOwnedStepQueryKeys` (validation.go), `IsServerOwnedParamKey` | `validators/serverOwnedQueryKeys.ts` | `v0151-save-door.test.ts`, `conformance.test.ts` |
1010
- | An endpoint a server-supplied credential will never be sent to (`credential_endpoint_unpaired`, warning) | `validateCredentialEndpointPairing`, `validateFamilyCredentialEndpointPairing` (validation.go) | `validators/credentialEndpoint.ts`, `validators/goUrl.ts` | `v0152-credential-endpoint.test.ts`, `conformance.test.ts` |
1011
- | The `examples:` block: 58 codes, one walker (ids, inputs, references, expectations, checkpoints, variants) | the examples walker (`ValidateExamples`) | `validators/examples.ts`, `validators/goUrl.ts` | `examples.test.ts`, `conformance.test.ts` |
1012
- | Orchestrator `.exons` frontmatter: spec, provider, `requirements.resources`, `tools.allow` withholds | `validateOrchestrator` (parser.go), `validateOrchestratorToolAllowWithholds` | `validators/exons.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
1013
- | Credential bindings (`stored/...`, inject_as, exclusivity) | `validateStepCredentialBindings` | `validators/credentialBindings.ts` | `validate.test.ts` |
1014
- | `input_schema` definition + ordering lint | `ValidateInputSchemaDefinition`, `LintInputSchemaFieldOrdering` | `validators/inputSchema.ts` | `validate.test.ts` |
1015
- | Step `output_schema` definition (reuses the input-schema subset) | `ValidateInputSchemaDefinition` (on `step.OutputSchema`, parser.go) | `validators/outputSchema.ts` (+ shared `inputSchema.ts`) | `validate.test.ts` |
1016
- | `quality_gate:` block (rubric/threshold/on_fail/goto) | `FlowParser.validateQualityGate` (parser.go) | `validators/qualityGate.ts` | `validate.test.ts` |
1017
- | Processing-operation type + per-operation config keys | `validateProcessingOperationShape` | `validators/processingOperations.ts` | `validate.test.ts`, `conformance.test.ts` |
1018
- | Step `max_duration` the engine cannot apply (`step_max_duration_ignored`, warning) | `validateStepMaxDurationIsApplied` (validation.go), `parseStepMaxDuration` (flowengine.steptimeout.go) | `validators/stepMaxDuration.ts` | `validate.test.ts`, `conformance.test.ts` |
1019
- | Go-template syntax | `validateTemplateExpression` (Parse step) | `template/gotmpl-syntax.ts` + `validators/templates.ts` | `gotmpl-syntax.test.ts`, `validate.test.ts` |
1064
+ | Area | Go source | JS module | Tested by |
1065
+ | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- | ------------------------------------------------------------- |
1066
+ | Required fields, start-step existence, per-step executor, reserved `.` in IDs, reserved id `orchestrator` | `validateBasicStructure`, `ValidateFlow` head | `validators/basicStructure.ts` | `validate.test.ts`, `conformance.test.ts` |
1067
+ | Executor URI shape (the ONE parser) + scheme | `ValidateFlow` executor-URL rule (parser.go), `ParseExecutorURLString` | `validators/executors.ts` | `validate.test.ts` |
1068
+ | Query/property/array-item schema + array constraints | `validateQueryParameters`, `validateProperties`, `validateArrayItems`, `validateArrayConstraints` | `validators/querySchema.ts` | `validate.test.ts` |
1069
+ | Response-expectation types + array items + `required` | `ValidateFlow` (response block), `validateSemantics` | `validators/responseExpectation.ts` | `validate.test.ts` |
1070
+ | Response expectation nothing reads (`response_expectation_unread`, warning) | `validateResponseExpectationIsRead` (validation.go) | `validators/responseExpectation.ts` | `validate.test.ts`, `conformance.test.ts` |
1071
+ | Error strategy (action, goto, max_delay, backoff, retry_on) | `validateErrorStrategy` | `validators/errorStrategy.ts` | `validate.test.ts` |
1072
+ | Retired `budget:` / `max_retries:` (flow, step, loop sub-step) and `campaign.budget_max_per_child` → `unknown_yaml_key` | `retiredGrammarKeys` + `KnownFields(true)` (parser.go) | `validators/retiredKeys.ts` | `validate.test.ts`, `conformance.test.ts` |
1073
+ | `next` references (save-door sentinels `null`/`orchestrator`), reachability and cycles (`end` is an ordinary step) | `validateNextLogic` (parser.go), `findReachableSteps`, `checkForCycles` | `validators/connectivity.ts` | `validate.test.ts`, `conformance.test.ts` |
1074
+ | Unknown keys at every level (`unknown_yaml_key`) and value kinds (`invalid_type`) | `KnownFields(true)` over the reference's types (parser.go); `knownKeys` in the spec | `validators/unknownKeys.ts` | `validate.test.ts`, `conformance.test.ts` |
1075
+ | `next.parallel` + orchestrator-next requirement | `validateNextLogic`, `validateOrchestratorNext` | `validators/nextLogic.ts` | `validate.test.ts` |
1076
+ | Expression functions (XOR package/function) | `validateExpressionFunctions` | `validators/expressionFunctions.ts` | `validate.test.ts` |
1077
+ | Expression-function catalog (`package:` refused, unknown `function:` refused) | `validateExpressionFunctionCatalog` (parser.go) | `validators/expressionFunctions.ts` | `validate.test.ts`, `conformance.test.ts` |
1078
+ | Expression-function USE (`{{ fn_* }}` must be in the catalog AND declared) | `validateExpressionFunctionUsage` (parser.go) | `validators/expressionFunctions.ts` | `validate.test.ts`, `conformance.test.ts` |
1079
+ | Loop / for_each / throttle | `validateLoop`, `validateForEach`, `validateThrottle` | `validators/loopForEachThrottle.ts` | `validate.test.ts` |
1080
+ | Loop sub-step id that shadows a loop-result summary field (`loop_sub_step_id_reserved`, warning) | `validateLoopSubStepIDCollision` (validation.loopbody.go) | `validators/loopForEachThrottle.ts` | `validate.test.ts`, `conformance.test.ts` |
1081
+ | Loop sub-step `next:` targets (same-loop only, sentinels, no parallel) | `validateLoopSubStepNext` (parser.go) | `validators/loopForEachThrottle.ts` | `validate.test.ts`, `conformance.test.ts` |
1082
+ | Orchestrator structure + campaign requires orchestrator | `validateOrchestrator`, `validateAndNormalizeCampaign` | `validators/orchestratorCampaign.ts` | `validate.test.ts` |
1083
+ | Campaign `max_credits_per_child` (decoded as int64, >= 0), `child_flows` | `CampaignConfig.Validate` (domain.campaign.go) | `validators/orchestratorCampaign.ts` | `validate.test.ts`, `conformance.test.ts` |
1084
+ | `tool_discovery` vocabulary, mock scenario `delay`, empty `output:` entry | `validateToolDiscoveryVocabulary`, `validateMockScenarioDelays`, `validateOutputParameters` (parser.go) | `validators/saveDoor.ts` | `validate.test.ts`, `conformance.test.ts` |
1085
+ | `executor_config` `${NAME}` references outside the key's scope (`executor_config_env_scope`) | `ValidateExecutorConfigEnvScopes` (parser.go) | `validators/executorConfigEnv.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
1086
+ | A step or loop sub-step `query:` declaring a server-owned key (`server_owned_query_key`) | `validateNoServerOwnedStepQueryKeys` (validation.go), `IsServerOwnedParamKey` | `validators/serverOwnedQueryKeys.ts` | `v0151-save-door.test.ts`, `conformance.test.ts` |
1087
+ | An endpoint a server-supplied credential will never be sent to (`credential_endpoint_unpaired`, warning) | `validateCredentialEndpointPairing`, `validateFamilyCredentialEndpointPairing` (validation.go) | `validators/credentialEndpoint.ts`, `validators/goUrl.ts` | `v0152-credential-endpoint.test.ts`, `conformance.test.ts` |
1088
+ | The `examples:` block: 58 codes, one walker (ids, inputs, references, expectations, checkpoints, variants) | the examples walker (`ValidateExamples`) | `validators/examples.ts`, `validators/goUrl.ts` | `examples.test.ts`, `conformance.test.ts` |
1089
+ | Orchestrator `.exons` frontmatter: spec, provider, `requirements.resources`, `tools.allow` withholds | `validateOrchestrator` (parser.go), `validateOrchestratorToolAllowWithholds` | `validators/exons.ts` | `v0150-save-door.test.ts`, `conformance.test.ts` |
1090
+ | Credential bindings (`stored/...`, inject_as, exclusivity) | `validateStepCredentialBindings` | `validators/credentialBindings.ts` | `validate.test.ts` |
1091
+ | `input_schema` definition + ordering lint | `ValidateInputSchemaDefinition`, `LintInputSchemaFieldOrdering` | `validators/inputSchema.ts` | `validate.test.ts` |
1092
+ | Step `output_schema` definition (reuses the input-schema subset) | `ValidateInputSchemaDefinition` (on `step.OutputSchema`, parser.go) | `validators/outputSchema.ts` (+ shared `inputSchema.ts`) | `validate.test.ts` |
1093
+ | `quality_gate:` block (rubric/threshold/on_fail/goto) | `FlowParser.validateQualityGate` (parser.go) | `validators/qualityGate.ts` | `validate.test.ts` |
1094
+ | Processing-operation type + per-operation config keys | `validateProcessingOperationShape` | `validators/processingOperations.ts` | `validate.test.ts`, `conformance.test.ts` |
1095
+ | Step `max_duration` the engine cannot apply (`step_max_duration_ignored`, warning) | `validateStepMaxDurationIsApplied` (validation.go), `parseStepMaxDuration` (flowengine.steptimeout.go) | `validators/stepMaxDuration.ts` | `validate.test.ts`, `conformance.test.ts` |
1096
+ | An EU-only residency beside an unpinned region-lane `ai://` call (`compliance_residency_unenforced`, warning) | `validateResidencyEnforcement` (validation.residency.go) | `validators/complianceResidency.ts` | `v0200-compliance-residency.test.ts`, `conformance.test.ts` |
1097
+ | Go-template syntax | `validateTemplateExpression` (Parse step) | `template/gotmpl-syntax.ts` + `validators/templates.ts` | `gotmpl-syntax.test.ts`, `validate.test.ts` |
1098
+ | A value piped into `default` (`template_default_piped`; error, warning in a loop body) | `pipedDefaultPipelines` (validation.templatedefault.go) | `template/gotmpl-default.ts` + `validators/templates.ts` | `v0210-template-default-piped.test.ts`, `conformance.test.ts` |
1020
1099
 
1021
1100
  ---
1022
1101
 
package/README.md CHANGED
@@ -116,7 +116,7 @@ Low-level: parse YAML into `{ flow?, parseErrors, parseWarnings }` without valid
116
116
 
117
117
  ### `SPEC_VERSION: string`
118
118
 
119
- The AIgentFlow flow-schema version this build tracks (e.g. `"2.820.0"`).
119
+ The AIgentFlow flow-schema version this build tracks (e.g. `"2.827.0"`).
120
120
 
121
121
  ### Options
122
122
 
@@ -183,14 +183,14 @@ interface ValidationIssue {
183
183
  - **`tool_discovery`** — `eager`/`lazy`/`off` on the flow, the orchestrator, and a step `query` (empty and templated values skipped).
184
184
  - **Mock scenarios** — each `delay` must be a Go duration (`100ms`, not `100`), judged by its written spelling: `0` saves, `0.0` does not.
185
185
  - **`output:`** — no empty-string entries.
186
- - **Templates** — Go `text/template` **syntax** across query, processing, and conditions.
186
+ - **Templates** — Go `text/template` **syntax** across query, processing, and conditions; and a value piped into `default` (`{{ .x | default "w" }}`, error; warning in a loop body — `default` takes the value first: `{{ default .x "w" }}`).
187
187
 
188
188
  ## What it does **not** check
189
189
 
190
190
  These need a live server / org context and are intentionally out of scope:
191
191
 
192
192
  - **Credentials** — whether a bound credential actually exists or is authorised.
193
- - **Model compliance** — the `compliance:` block is enforced against the provider catalogue at flow-create time on the server.
193
+ - **Model compliance** — the `compliance:` block is enforced against the provider catalogue at flow-create time on the server. (The one catalogue-free part, the warning `compliance_residency_unenforced` for an EU-only residency beside an unpinned call, is checked here.)
194
194
  - **`.exons` document bodies** — whether an inline `.exons` document parses and whether its tags can render (`exons_attributes`) needs the `.exons` template engine, which this package does not embed.
195
195
  - **Template field resolution** — whether `.data.x.y` will actually be populated at runtime (we validate syntax, not data flow).
196
196
  - **Publish gates** — `visibility`/`classification`/template-metadata publish rules are server- and org-context dependent.