From 1d75e0b45e7d92f021b2a614db53bde6611c5358 Mon Sep 17 00:00:00 2001 From: rg4444 Date: Wed, 20 May 2026 11:51:48 +0000 Subject: [PATCH] =?UTF-8?q?feat(2.3.0):=20Algorithm=20Cards=20=E2=80=94=20?= =?UTF-8?q?optional=20governance=20wrapper=20for=20algorithms=20behind=20r?= =?UTF-8?q?esource=20targets?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new OPTIONAL artifact category, Algorithm Cards, that supplies governance metadata (intent, IO contract, ownership, lifecycle, validation, optional extensions for ML/crypto/privacy/risk/prompt) for one algorithm invoked behind a resource target. Cards live in the package's algorithms/ folder and validate against the new algorithm-card schema. Resource mapping targets gain an optional algorithm_card reference. Fully additive, backward-compatible — every package valid under 2.2.x stays valid under 2.3.0. Algorithm Cards EXTEND the Resources cornerstone — they do NOT become a fifth cornerstone. The four cornerstones (BPMN, DMN, CMMN, Resources + Mapping) remain authoritative and unchanged. Additions: - specification/13-algorithm-cards.md (new normative chapter) - schemas/algorithm-card.schema.json (new normative schema) - specification/11-semantic-validation.md: new SEM-012 rule - specification/10-conformance-checklist.md: new optional conformance block - specification/02-process-cornerstones.md: clarifying note - README.md, CHANGELOG.md, VERSION: 2.2.0 -> 2.3.0 - schemas/uapf-manifest.schema.json: optional algorithm_cards + paths.algorithms - schemas/resource-mapping.schema.json: optional target.algorithm_card - examples/approve-expense-l4: one Card added to demonstrate the feature - .github/workflows/validate.yml: card validation step --- CHANGELOG.md | 30 +++ README.md | 2 + VERSION | 2 +- .../policy_lookup_assistant.card.yaml | 53 +++++ .../resources/mappings.yaml | 1 + examples/approve-expense-l4/uapf.yaml | 2 + examples/archives/approve-expense-l4.uapf | Bin 2690 -> 3906 bytes schemas/algorithm-card.schema.json | 178 ++++++++++++++ schemas/resource-mapping.schema.json | 4 + schemas/uapf-manifest.schema.json | 8 + specification/02-process-cornerstones.md | 8 + specification/10-conformance-checklist.md | 12 + specification/11-semantic-validation.md | 19 +- specification/13-algorithm-cards.md | 221 ++++++++++++++++++ 14 files changed, 538 insertions(+), 2 deletions(-) create mode 100644 examples/approve-expense-l4/algorithms/policy_lookup_assistant.card.yaml create mode 100644 schemas/algorithm-card.schema.json create mode 100644 specification/13-algorithm-cards.md diff --git a/CHANGELOG.md b/CHANGELOG.md index d311f9e..a449005 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,35 @@ # Changelog +## [2.3.0] - 2026-05-20 + +### Added +- New OPTIONAL artifact category — Algorithm Cards — defined in + `specification/13-algorithm-cards.md` and validated by + `schemas/algorithm-card.schema.json`. A Card is a typed, versioned + governance wrapper for a single algorithm invoked behind a resource + target. Cards live in the package's `algorithms/` folder (path + configurable via `paths.algorithms`) and supply intent, IO contract, + ownership, lifecycle, validation history, and OPTIONAL extensions + for ML, crypto, privacy, risk, and prompt-based implementations. +- Manifest schema gains two OPTIONAL top-level properties: + `algorithm_cards` (boolean) and `paths.algorithms` (string). Neither + is required; both live outside the closed `cornerstones` block. +- Resource mapping schema gains one OPTIONAL `algorithm_card` property + per target, referencing a Card by `id` or relative path. +- New validation rule `SEM-012` (ERROR): Algorithm Card reference does + not resolve. +- New OPTIONAL conformance block in `10-conformance-checklist.md` for + implementations that support Algorithm Cards. +- New example `examples/approve-expense-l4` now demonstrates a Card + attached to one of its resource targets. + +### Note +- Fully additive, backward-compatible. Every package valid under 2.2.x + remains valid under 2.3.0. Algorithm Cards extend the Resources + cornerstone — they do NOT become a fifth cornerstone. The four + cornerstones (BPMN, DMN, CMMN, Resources + Mapping) remain + authoritative and unchanged. Hence a minor bump. + ## [2.2.0] - 2026-05-17 ### Added diff --git a/README.md b/README.md index af1ae55..8afe619 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ UAPF is a disciplined format for storing and versioning organizational processes - Conformance checklist: [`specification/10-conformance-checklist.md`](specification/10-conformance-checklist.md) - Semantic validation: [`specification/11-semantic-validation.md`](specification/11-semantic-validation.md) - YAML guidelines: [`specification/12-yaml-guidelines.md`](specification/12-yaml-guidelines.md) +- Algorithm Cards: [`specification/13-algorithm-cards.md`](specification/13-algorithm-cards.md) ## Schemas (normative) - UAPF manifest schema: [`schemas/uapf-manifest.schema.json`](schemas/uapf-manifest.schema.json) @@ -66,6 +67,7 @@ UAPF is a disciplined format for storing and versioning organizational processes - Lifecycle metadata schema: [`schemas/lifecycle.schema.json`](schemas/lifecycle.schema.json) - Policies schema: [`schemas/policies.schema.json`](schemas/policies.schema.json) - MCP tool schemas: [`schemas/mcp-tools.schema.json`](schemas/mcp-tools.schema.json) +- Algorithm Card schema: [`schemas/algorithm-card.schema.json`](schemas/algorithm-card.schema.json) ## Normative boundaries Only the following are normative SSOT for UAPF v1: diff --git a/VERSION b/VERSION index ccbccc3..cc6612c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2.0 +2.3.0 \ No newline at end of file diff --git a/examples/approve-expense-l4/algorithms/policy_lookup_assistant.card.yaml b/examples/approve-expense-l4/algorithms/policy_lookup_assistant.card.yaml new file mode 100644 index 0000000..62e5b34 --- /dev/null +++ b/examples/approve-expense-l4/algorithms/policy_lookup_assistant.card.yaml @@ -0,0 +1,53 @@ +kind: uapf.algorithm.card + +id: algo.expense_approval.policy_lookup_assistant +version: "1.0.0" +name: "Policy lookup assistant" +intent: > + Assists evaluation of expense-approval policy by retrieving the + applicable internal policy text for a given expense category and + amount, and presenting it in a structured form for the approver + and for the DMN policy decision. + +algorithm_kind: extractor + +io: + inputs: + - id: expense_category + type: string + - id: expense_amount + type: decimal + unit: EUR + outputs: + - id: applicable_policy_text + type: string + - id: policy_section_ref + type: string + +implementation: + type: external + medium: vendor_saas + uri: "https://example.com/policy-api/v1/lookup" + hash: "sha256:0000000000000000000000000000000000000000000000000000000000000000" + +determinism: deterministic +side_effects: external_call + +owners: + - type: team + id: finance-process-office + contact: finance-process-office@example.com + +lifecycle: + status: approved + since: "2026-05-20" + +validation: + last_validated: "2026-05-20" + test_suite: ../tests/algorithms/policy_lookup_assistant.test.yaml + validator: finance-process-office + +audit: + log_inputs: redacted + log_outputs: full + retention: "1y" diff --git a/examples/approve-expense-l4/resources/mappings.yaml b/examples/approve-expense-l4/resources/mappings.yaml index b4947d0..ceac9fe 100644 --- a/examples/approve-expense-l4/resources/mappings.yaml +++ b/examples/approve-expense-l4/resources/mappings.yaml @@ -6,6 +6,7 @@ targets: capabilities: - capability.policy.lookup - capability.decision.assist + algorithm_card: algo.expense_approval.policy_lookup_assistant - id: role.manager type: human_role diff --git a/examples/approve-expense-l4/uapf.yaml b/examples/approve-expense-l4/uapf.yaml index 630275f..d65cc05 100644 --- a/examples/approve-expense-l4/uapf.yaml +++ b/examples/approve-expense-l4/uapf.yaml @@ -16,6 +16,8 @@ paths: cmmn: cmmn resources: resources metadata: metadata + algorithms: algorithms +algorithm_cards: true owners: - type: team id: finance-process-office diff --git a/examples/archives/approve-expense-l4.uapf b/examples/archives/approve-expense-l4.uapf index 06291b1a9c6be8b3d35b011bf471d11f1f1133f2..e99ddbcd80ba1adcf3ad358ebdd6a190c11aa9f7 100644 GIT binary patch delta 2425 zcmb7Gc|6o>7axWhV`;I>gs!FN64%z7vQ#D}yGWyyWSTJyV`iEeTWD;BDa0srt=S{{ z8dsN*EfkdoNh(Vk3`!;G{>J-utNZr;@t)u3e4gL$d7g8g^Eu!1e9tdjrd5GqZw(fb z27y2#pc5t)E+GW}AQu4;$X^fyf&sHfP)IXdl$H-J_KFdits@@k|5;SfIZ?1S*=A?} zdb=8BPk)U+ab}zHIb3Es%@q` zJqP8KTrUYa67d^yaGbcxz--@HKlVp+g3-CpNw2OPj|1kyGH~3BAmUtrWw0lUd~C@xSh*}(iUFn|*}n^+q|B1c zjd>rH4Ky8#3^u#i|oD^&m#WdDPLFNT8G3dHyjeH|L@gmlHZ zOEOwW&m7ZXFAb9i0yoS>WIKY)l9Lm;`_>dZ=1B&ka^863^KC;MH%N+3tf8_GrMFw_ zU|eos=3eQ+lt@xP;Yo352DCm?<|3mY2V9yFcyGgsw|l*PZPD39n7;h86Fm#;yo_OJ+(^xeE&>e2ZZVWOd|G%>bUCRUr@v z0n|3toksShV%=%lJ{SsxK=Poi=eUN|LSidzGMisxqUXlJ)Jt;c8D%v39m$6`oZlV_ zs_Px|mryx7Y?W|xaL+{nyh4C|{?MP1r7{`e=}oyxhv;^xrOas~CdN^q1X;1sNYA0V zn~{}J-M;B)wCA?_;I^FYeuajqi8u=G_5Kk|P$herdu5uJRn24$=q}YY7n+ZkI4!DG z*RWrm*ZY?W+I}!PZHKeH|6nmEzQ*i8$7Ds;M)Mu^y`xPbrl)F4mj>VE^)%e7yPk4k z{NQ=^>F#;Ai~Hu2(Q4hzlXDA&R>e-)R7?z2^Qt?@3H?(B)Uv`}Oh(U(f?&o0!+ zx6yq|srQbbUC0Vw?kpgSDL5HFrG{`FvG-5JrZ!5fU2+Nj}SMabn zE;)X+Rkm9=HB6WLFn$9v+A$yu5v--tE+p4SzgxZ(-p>$j;L6g=4~}CcCeqW~tWpe& z#tT|62k%KfYFh-mb>-uQ1T6ddFFP=M3EbWM{1l6WBKY*g;iSP$wpu4qb=p89}zd!k42xFy@WZpcds{$(kCJ~*zXDQ@M) zRJpGUZq=W`l}PEgfJQ~W9OE%pUp=V0ZJnb!J>#*KM<((-i&hlsPwM9@d#4YbkXkS~ zWtB=D^ZihAp>TJ#;>t=A7cnOU8LUj(-8C00)nWE(M(b& zWA?A^h&U3rca^x+O66JA5!#)Ng_i?%;N6gR9S==uO=PgcaDwcX-osU zbIzqm$9BYz+B52NllH!S>49i@dQI{iiL3jEbN#^M#Q-bA1!JO7i#6FfCU2AOyrUS_ z_uxIUYIq5E1=0(BC-x)FoYxutJO`9w4!|%75bKkOEDHzzAjvP=KL;MG)B)2~K()$( zSmh$}Rdj&{0fvB}H28nFUclG7X2{C_m? z&*Oi@@2g*a9%;aj5YC5`2$TM=n14j}d!uWje4OF-*1|wsAdo2V6as`5DbD};3#6;= AR{#J2 delta 1131 zcmX>k*CbjW;LXe;!oa}5!Ekm%Z}g;%jebIm3=FS;m=h>knplvgSDBcbQyO^MkJ*rC z&vWe>mW91tTbA20E;4txBgp=^;`WM4&6D3gez(}28_E}>({F3sr)DjEhCz5)p!yQo zyoj5x72Ge?_{eZ&`!IcfvE_BB!+B<#^TKUk4>jyIufMms`Cpu*-jv)`W^4-?k2=iM zKJ4?ND&trT*9XDcA|CeW?H@k<{Kv@uK})o`@r@6xwv6?9S`|14~E8-GJX1nmwH`8qkFN8Tc z<(B>Y*LmMYo%wbdqwp_3)~-CRS&O7DR&U$wX7I-2(IUnf%**B8o#=XXW6@QU;}Vu! zQJ$|Eiatz{+H-QLOr%WkmxxyzY_29&=4E`@k$U*hl0M`=by{+3>q*Z|jGNc2)N}oj@N(e`hFgng23)$) zu&wp#FUcERtnwa3Ytqij3P`?^m+uBs2}(fWYX}f zZc})bx^6wU*eC1Fhi9kcGFjJVPA^zJE3`D@-}^uM=kAnVPkS9+_)j$LtU78ePL5}r zzyS(%q1SvnCSPSWWb~TM&gPTI$RxsyJDUKb6AYF#f+%>V3GhbMhLS`eI-uGt87B+! zOB;Yv47w(i^n#*En|X3Sr=$orO_RHLrI>.) or a relative path to the .card.yaml file (see chapter 13)." } } }, diff --git a/schemas/uapf-manifest.schema.json b/schemas/uapf-manifest.schema.json index 8599343..7d425f2 100644 --- a/schemas/uapf-manifest.schema.json +++ b/schemas/uapf-manifest.schema.json @@ -107,6 +107,10 @@ "metadata": { "type": "string", "default": "metadata" + }, + "algorithms": { + "type": "string", + "default": "algorithms" } } }, @@ -252,6 +256,10 @@ "guardrails": { "type": "string", "description": "Path, relative to the package root, to the guardrails file enforced at every capability call (e.g. 'resources/guardrails.yaml')." + }, + "algorithm_cards": { + "type": "boolean", + "description": "Whether this package contains Algorithm Cards (see chapter 13)." } }, "$defs": { diff --git a/specification/02-process-cornerstones.md b/specification/02-process-cornerstones.md index 38e4c9a..e33b47f 100644 --- a/specification/02-process-cornerstones.md +++ b/specification/02-process-cornerstones.md @@ -34,3 +34,11 @@ Resources describe who/what executes work and how tasks bind to those resources. - MCP tools/endpoints. UAPF does not redefine BPMN/DMN/CMMN semantics; it packages them with governance and bindings. + +### Algorithm Cards (extension) + +Resource targets MAY carry deeper governance metadata via Algorithm +Cards (see chapter 13). Algorithm Cards extend, but do not constitute, +the Resources cornerstone. The four cornerstones remain BPMN, DMN, +CMMN, and Resources + Mapping. + diff --git a/specification/10-conformance-checklist.md b/specification/10-conformance-checklist.md index e86cecb..3b35cf0 100644 --- a/specification/10-conformance-checklist.md +++ b/specification/10-conformance-checklist.md @@ -71,4 +71,16 @@ An implementation claiming UAPF conformance MUST satisfy the following. - [ ] Validates version fields are strings, not numbers - [ ] Rejects invalid type coercions in required fields + +## Algorithm Cards (13) — OPTIONAL + +If an implementation supports Algorithm Cards: + +- [ ] Recognizes `algorithm_cards: true` and `paths.algorithms` in the manifest +- [ ] Validates each `*.card.yaml` against `schemas/algorithm-card.schema.json` +- [ ] Resolves `target.algorithm_card` references during workspace validation (SEM-012) +- [ ] Exposes Cards via MCP under `uapf://algorithms/...` when MCP export is enabled +- [ ] Includes Card reference in `uapf.resolve_resources` output when target carries one +- [ ] Ignores Card extension blocks (`ml`, `crypto`, `privacy`, `risk`, `prompt`) it does not understand without raising errors + An implementation MUST state which sections it supports. diff --git a/specification/11-semantic-validation.md b/specification/11-semantic-validation.md index 242f9d1..2ccb5ab 100644 --- a/specification/11-semantic-validation.md +++ b/specification/11-semantic-validation.md @@ -91,6 +91,22 @@ FOR EACH file IN dmn/*.dmn: ASSERT file CONTAINS ``` + +### 11.3.4 Algorithm Card Reference Integrity + +When a resource target carries an `algorithm_card` property, the +referenced Card MUST resolve. + +**Validation Rule SEM-012:** +``` +FOR EACH target IN resources/mappings.yaml: + IF target.algorithm_card IS PRESENT: + IF target.algorithm_card MATCHES /^algo\./: + ASSERT target.algorithm_card EXISTS as id IN any algorithms/*.card.yaml + ELSE: + ASSERT target.algorithm_card EXISTS as path RELATIVE TO package root +``` + ## 11.4 Error Codes | Code | Severity | Description | @@ -106,9 +122,10 @@ FOR EACH file IN dmn/*.dmn: | SEM-009 | ERROR | Duplicate binding for same source | | SEM-010 | WARNING | Fallback target not defined | | SEM-011 | ERROR | Cornerstone file missing diagram interchange (DI) | +| SEM-012 | ERROR | Algorithm Card reference does not resolve | ## 11.5 Conformance -- Implementations MUST validate SEM-001 through SEM-003, SEM-007 through SEM-009, and SEM-011 +- Implementations MUST validate SEM-001 through SEM-003, SEM-007 through SEM-009, SEM-011, and SEM-012 - Implementations SHOULD validate SEM-004 through SEM-006 and SEM-010 - Implementations MUST report error codes with messages diff --git a/specification/13-algorithm-cards.md b/specification/13-algorithm-cards.md new file mode 100644 index 0000000..d0aed31 --- /dev/null +++ b/specification/13-algorithm-cards.md @@ -0,0 +1,221 @@ +# 13 — Algorithm Cards (Normative) + +## 13.0 Purpose + +This chapter defines the **Algorithm Card** artifact: a typed, versioned +governance wrapper for a single algorithm invoked behind a resource target. +A Card supplies the metadata required to identify, audit, validate, and +replace an algorithm without requiring the algorithm's implementation to +live inside the UAPF package. + +Algorithm Cards extend the Resources cornerstone (see chapter 02). They +do NOT constitute a new cornerstone. The four cornerstones — BPMN, DMN, +CMMN, Resources + Mapping — defined in chapter 02 remain authoritative +and unchanged. + +## 13.1 Scope + +The Resources cornerstone declares *where* work is dispatched +(`ai_agent`, `human_role`, `system_api`, `mcp_tool`, `external_service`). +It does NOT declare *what* the dispatched algorithm does, who is +accountable for it, when it was last validated, or how it behaves under +uncertainty. Algorithm Cards fill that gap. + +A Card is OPTIONAL. Packages whose resource targets are sufficiently +described by their existing target declaration MAY omit Cards entirely. +Packages whose targets invoke probabilistic models, learned classifiers, +third-party services, or any algorithm whose behaviour is not self-evident +from the target declaration alone SHOULD provide a Card per such target. + +UAPF does NOT standardize through this chapter: +- the source language or representation of algorithms, +- the runtime that executes them, +- the format of training data, model weights, or external services + referenced by a Card, +- any specific AI, ML, cryptographic, or privacy technique. + +A Card describes; it does not implement. + +## 13.2 The Algorithm Card artifact + +A Card MUST be a YAML file under the package's `algorithms/` folder. + +The folder location is configured by `paths.algorithms` in the manifest; +the default value is `algorithms`. + +A Card MUST validate against `schemas/algorithm-card.schema.json`. + +A Card file MUST use the suffix `.card.yaml`. + +## 13.3 Required fields + +Every Card MUST declare: + +| Field | Constraint | +|---|---| +| `kind` | The literal string `uapf.algorithm.card` | +| `id` | Globally unique identifier, pattern `^algo\.[a-z0-9][a-z0-9._-]+$` | +| `version` | Semantic version string (chapter 12 quoting rules apply) | +| `name` | Human-readable title | +| `intent` | Plain-language description of what the algorithm does | +| `algorithm_kind` | One of: `formula`, `classifier`, `extractor`, `ml_model`, `rule_table`, `crypto`, `redactor`, `router`, `validator`, `aggregator`, `transformer`, `emitter`, `other` | +| `io` | Typed input/output contract | +| `implementation` | Discriminated by `type`: `inline`, `external`, or `composite` | +| `owners` | At least one owner, structurally consistent with `metadata/ownership.yaml` | +| `lifecycle` | Status, structurally consistent with `metadata/lifecycle.yaml` | + +## 13.4 Implementation forms + +The `implementation` block declares where the algorithm body lives. It is +a discriminated union on the `type` field. + +### 13.4.1 `inline` + +The algorithm body is present in the Card. Used when the algorithm is +declaratively expressible in a supported language. The Card MUST declare: + +- `type`: the literal `inline` +- `language`: one of `feel`, `dmn`, `rego`, `regex`, `sql`, `wasm` +- `body`: the algorithm body as a string, OR +- `body_ref`: a path to a file in the package containing the body + +Exactly one of `body` or `body_ref` MUST be present. + +### 13.4.2 `external` + +The algorithm body lives outside the package. The Card MUST declare: + +- `type`: the literal `external` +- `medium`: one of `llm_prompt`, `ml_model`, `http_api`, `mcp_tool`, + `native_binary`, `crypto_module`, `vendor_saas` +- `uri`: addressable reference (URL, file path, registry reference) +- `hash`: SHA-256 of the referenced artifact, format `sha256:` +- `runtime`: OPTIONAL medium-specific runtime configuration + +### 13.4.3 `composite` + +The Card refers to two or more other Cards composed together. The Card +MUST declare: + +- `type`: the literal `composite` +- `composed_of`: ordered list of `{ ref, version }` referencing other + Cards by `id` + +Composite resolution is recursive. Implementations MUST detect cycles +(see SEM-008 in chapter 11). + +## 13.5 IO contract + +The `io` block MUST contain `inputs` and `outputs`, each a list of +field declarations. Each field MUST declare `id` and `type`. Each field +MAY declare `schema` (path to JSON Schema for complex types), `unit` +(SI unit, ISO 4217 currency, or domain-specific symbol), `cardinality` +(`single` | `optional` | `array` | `stream`; default `single`), and +`constraints` (a JSON Schema constraint subset). + +## 13.6 Optional fields + +A Card MAY declare: + +| Field | Purpose | +|---|---| +| `determinism` | `deterministic` (default), `stochastic`, `learned` | +| `confidence` | Uncertainty model: `type`, `threshold`, `below_threshold` action | +| `side_effects` | `pure` (default), `reads_state`, `writes_state`, `external_call` | +| `complexity` | Latency and complexity-class declarations | +| `failure_mode` | Behaviour when output cannot be produced | +| `limitations` | Free-text list of known limitations | +| `reference` | Legal / methodology / standard citation | +| `validation` | `last_validated`, `test_suite`, `validator`, `methodology`, `metrics` | +| `audit` | Logging configuration: `log_inputs`, `log_outputs`, `retention` | + +## 13.7 Type-specific extensions + +A Card MAY include OPTIONAL extension blocks. Extensions are scoped by +`algorithm_kind` and carry domain-specific metadata that does not fit the +universal core. The following extensions are defined in this version: + +- `ml` — applies when `algorithm_kind` is `ml_model` or `classifier` + with an ML implementation. Links to Model Card URL, training data + reference, fairness analysis. +- `crypto` — applies when `algorithm_kind` is `crypto`. FIPS certificate, + algorithm identifier, key length, quantum-resistance flag. +- `privacy` — applies when the algorithm processes personal data. + Technique, parameters, re-identification risk class. +- `risk` — algorithmic risk classification and human-oversight + requirements. +- `prompt` — applies when `implementation.medium` is `llm_prompt`. + Model identifier, prompt hash, temperature, max tokens. + +Implementations MUST ignore extensions they do not understand. +Extensions MUST NOT contradict the universal core. + +## 13.8 Relationship to Resource targets + +A resource target in `resources/mappings.yaml` MAY reference a Card via +the optional `algorithm_card` property. The reference is the Card's `id` +or a relative path to the Card file. + +```yaml +targets: + - id: classifier_x + type: ai_agent + name: "Generic classifier" + algorithm_card: algo.example.classifier_x +``` + +The Card and the target describe complementary facets of the same +resource: the target describes the *binding surface* (how to reach the +algorithm), the Card describes the *algorithmic surface* (what the +algorithm does, with what guarantees). + +A target MAY reference at most one Card. Multiple targets MAY reference +the same Card. Implementations MUST resolve Card references during +validation; unresolved references MUST raise SEM-012. + +## 13.9 Manifest declaration + +A package containing Algorithm Cards SHOULD declare: + +```yaml +algorithm_cards: true +paths: + algorithms: algorithms +``` + +`algorithm_cards` is a manifest-level boolean declaring intent. +`paths.algorithms` declares the folder name if not the default. Both +fields are OPTIONAL and live at manifest top level — not inside the +closed `cornerstones` block. + +## 13.10 Testing + +Per-Card tests SHOULD be stored under +`tests/algorithms/.test.yaml`. + +Tests carry a uniform shape regardless of Card `algorithm_kind` or +`implementation.type`: input cases, expected outputs, and a tolerance +declaration. Deterministic algorithms use exact-match tolerance; +stochastic algorithms use distributional tolerance with explicit +pass-rate thresholds. + +A passing test run is the operational definition of validation. CI +SHOULD update `validation.last_validated` on the Card when the test +suite passes against the current `implementation.hash` (for external) +or `body_ref` content hash (for inline). + +The detailed test format is non-normative and lives in implementation +guides. + +## 13.11 Cards in MCP export + +When a package is exported to MCP per chapter 06, Cards MUST be +exposable as resources under `uapf://algorithms/...` and queryable via +`uapf.list` and `uapf.get_artifact`. + +The `uapf.resolve_resources` tool MUST include the Card reference in +the resolved binding when a target's `algorithm_card` is present. + +## 13.12 Conformance + +See chapter 10 for the Algorithm Cards conformance section.