Skip to content

Teaching examples that run, each built from the specification beside it - #1

Open
dialexpert wants to merge 19 commits into
devfrom
feat/flow-patterns-publish-ready
Open

Teaching examples that run, each built from the specification beside it#1
dialexpert wants to merge 19 commits into
devfrom
feat/flow-patterns-publish-ready

Conversation

@dialexpert

@dialexpert dialexpert commented Aug 31, 2026

Copy link
Copy Markdown
Member

Навчальні приклади BPMN для платформи MEF.DEV: десять моделей, кожна зібрана зі специфікації, що лежить поруч, і перевірена на стенді.

Склад

Група Модель Що показує
01 · Basics first-flow Input — payload виклику, #Previous — результат попереднього кроку
02 · Errors error-as-branch збій — це гілка діаграми; виняток несе лише #PreviousData
03 · Configuration service-config, use-config налаштування живуть в окремому Flow
04 · Pagination paged-fetch спершу план сторінок, далі Multi Instance
05 · Events raise-event крок піднімає подію і працює далі
06 · Streaming stream-response читання відповіді потоком, чанк за чанком
07 · Triggers http-start стартова подія вирішує, як до Flow дістатися
08 · Agents structured-prompt запит до моделі як типізовані дані, не як рядок
09 · Files archive-and-link файл живе у сховищі, а назад іде посилання

Відкладені (parked/): ask-model, archive-and-send, ai-completion — з причинами у власних специфікаціях.

Контракт специфікації

Ключі верхнього рівня: name, config, input, steps, stores, types, externalTypes, libs, outcomes, documentation, generate.

Ключі кроку: id, name, expression | function + params, note, risky, raises.

Ключі сховища: id, name, type (File, Folder, MSSQL.Procedure…), connection, object, usedBy.

Інструменти

tools/build.py збирає модель зі специфікації: gen дає каркас, далі проходи розкладки, наприкінці — перевірка.

Прохід Що робить
relayout, straighten верстка зверху вниз, ортогональні маршрути
split_shared_data кожній кінцевій події — власний елемент даних
add_boundary_event гранична подія, яку крок піднімає з коду
add_stores сховища даних із блоку stores, кожне привʼязане до свого кроку
add_types, add_examples, add_notes типи, приклади відповідей, коментарі
fit_notes, place_notes, place_labels, place_data_labels, snap_associations розміри й розміщення

tools/verify.py — одинадцять правил читабельності і пʼять правил прикладів. Зараз: 11 моделей, 0 порушень.

Крок gen живе в graph-api-files-sync/Tools/bpmn_forge.py; build.py знаходить його за змінною BPMN_FORGE. Він лишається там, бо читає каталог вбудованих функцій із вихідного коду закритого бекенду.

Перевірено на стенді

Усі дев'ять прикладів скомпільовані й запущені, кожен своїм прикладом входу: HTTP 200, справжні дані. archive-and-link повертає живе посилання на архів.

Обмеження, записані в прикладах

  • object сховища даних береться дослівно: ні {Input.x}, ні Input.x там не підставляються.
  • Запис файла не створює відсутніх тек — теку робить окремий крок.
  • LocalFolder.AddFolderToZip недосяжний із моделі: він бере CompressionLevel, а System.IO.Compression не входить у посилання компілятора потоків.
  • AI/Completions не компілюється у вузлі-задачі: її тіло вживає CT і Action.BoundaryEvents, а тип параметра Messages не резолвиться.
  • Один підйом граничної події коштує близько 0,2 с — це гілка конвеєра, а не надсилання.

Передумова

Спершу імпортувати 03-config-as-flow/service-config.bpmn у tenant-бібліотеку під іменем flow-patterns-config і скомпілювати. Решта моделей резолвить activities://bpmn-mnemo/tenant/<бібліотека>/flow-patterns-config/#latest.

Пов'язане

  • graph-api-files-sync/Tools/BPMN-FORGE.md — опис gen, правил BF-* і меж інструмента
  • Natec.Workflow.Core/Services/BuiltinFunctions/BuiltinFunctionsProvider.cs — каталог вбудованих функцій, проти якого звіряються приклади

dialexpert and others added 2 commits August 31, 2026 22:02
Every model was imported and compiled on the platform, and the diagnostic read
back. Six defects kept eleven of the fourteen from compiling:

- stale RestApi and RestApi/GET declarations omitted the Timeout parameter that
  the engine's inlined body references, so the identifier bound to the type
  System.Threading.Timeout (CS0119);
- a leftover TestCodeAction stub declared a string[] return and returned
  nothing. The engine emits a method for every declared Code Action, called or
  not, so the stub failed the whole model (CS0161);
- HandleException received #Previous where it needs #PreviousData, leaving the
  Exception unreachable in the branch that only a failure reaches;
- two models read Parameters.config without declaring the parameter;
- the Config type of the configuration Flow declared fewer fields than its
  consumers read: to_email and basic_auth were used but never declared. Its
  own comment had listed them as intended since the first commit.

Node labels are English now. Identifiers are untouched, so sequence flows,
associations and the diagram still resolve, and event names — which the
event-based gateway matches branches by — are left exactly as they were.

Nine of the fourteen models now compile on their own. The remaining five need a
companion Flow or a stand configuration that this repository does not ship.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The root README has been English from the start; the pattern guides, the type
design chapter and the catalogue were not, which left the publish target
unusable for the reader it is published for.

Translated with the structure preserved: same headings and levels, same table
columns and row order, same code blocks. In CATALOGUE.md every count, model
path and reserved-word list is byte-identical to before; only prose and column
headers changed.

Adds a "Companion Flows" section to the group index. A Flow takes its settings
from a separate configuration Flow through a Call Activity
(activities://bpmn-mnemo/<libType>/<libName>/<flowName>/#latest) and declares
that Flow's shared types as external (types://external/<lib>/<Type>). The
indirection is what keeps a model independent of its environment and keeps one
declaration of a type instead of a copy per Flow — and it is also why an
example that references a companion will not compile until the companion exists
in the target library, under the name the reference uses. The table says which
example needs which.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T16:31:03.897103Z 1218245 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4a086a86c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread flow-patterns/README.md Outdated
Comment on lines +49 to +50
environment you import into. Every other example in the table of contents above
compiles on its own.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Document every required companion flow

The standalone-compilation claim is false for at least 07-triggers/http-route-start.bpmn, whose Call Activity targets the environment-only chat-compleation-call flow at lines 46–49, despite this flow being absent from the import table. The ai-completions.bpmn row is also incomplete because that model additionally calls the pinned numeric target activities://bpmn/personal/12/1726/13. Users following these new instructions will still encounter missing-flow compilation failures, so list all required targets or exempt these examples from the claim.

Useful? React with 👍 / 👎.

The table missed two required targets, so the standalone-compilation claim was
false where it mattered most — for a reader on a different stand.

- `07-triggers/http-route-start.bpmn` reaches `ama_base_agent` and
  `chat-compleation-call` in the tenant library `AI_Agents_Shared`. It compiled
  during review only because those flows happened to exist on that stand, which
  is the accident this table exists to remove.
- `08-ai-agents/ai-completions.bpmn` also carries the version-pinned target
  `activities://bpmn/personal/12/1726/13`, which the mnemonic-only reading of
  the models did not surface.

Both reference forms are now named in the text: the mnemonic one resolves by
name and follows `#latest`; the numeric one pins a version, carries no name and
resolves only in the environment its identifiers came from.

Found by the automated review on this pull request.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dialexpert dialexpert changed the title Feat/flow patterns publish ready Flow patterns: publish-ready Aug 31, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 673e06e71d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<extensionElements>
<gp:globalParameter name="CodeActionsTypes">["Action","Function"]</gp:globalParameter>
<gp:globalParameter name="InnerTypes">[{"name":"Config","definition":" public class Config\r\n {\r\n /*логін\r\n пароль\r\nконнешн до бази\r\nнтв-айді\r\nмоде\r\nto\r\nfrom\r\nto_error\r\nfrom_error*/\r\n public string login { get; set; }\r\n public string password { get; set; }\r\n public string db_connection_str { get; set; }\r\n public string value { get; set; }\r\n public int id { get; set; }\r\n }","isNativeDefinition":true},{"name":"ErrorResponse","definition":"{\r\n \"$schema\": \"http://json-schema.org/draft-06/schema#\",\r\n \"$ref\": \"#/definitions/ErrorResponse\",\r\n \"definitions\": {\r\n \"ErrorResponse\": {\r\n \"type\": \"object\",\r\n \"additionalProperties\": true,\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Data\": {\r\n \"title\": \"The Error Data\",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Data\": {\r\n \"title\": \"The Data Schema\",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n }\r\n }\r\n },\r\n \"ResolveUrl\": {\r\n \"title\": \"The Resolve Url Link\",\r\n \"type\": \"string\"\r\n }\r\n }\r\n },\r\n \"ResolveUrl\": {\r\n \"title\": \"The Resolve Url Link\",\r\n \"type\": \"string\"\r\n },\r\n \"extraData\": {\r\n \"title\": \"The Error Extra Data \",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"operationDuration\": {\r\n \"title\": \"The Operation Duration\",\r\n \"type\": \"integer\"\r\n }\r\n }\r\n }\r\n },\r\n \"title\": \"ErrorResponse\"\r\n }\r\n }\r\n}","isNativeDefinition":false},{"name":"SystemException","definition":"{\r\n \"$schema\":\"http://natec.tech/simpleschema\",\r\n \"$ref\":\"#/definitions/SystemException\",\r\n \"definitions\":{\r\n \"SystemException\":{\r\n \"type\":\"object\",\r\n \"properties\":{\r\n \"Exception\":{\r\n \"type\":\"types://core/System.Exception\"\r\n },\r\n \"info\":{\r\n \"type\":\"string\"\r\n }\r\n },\r\n \"title\":\"SystemException\"\r\n }\r\n }\r\n}","isNativeDefinition":false}]</gp:globalParameter>
<gp:globalParameter name="InnerTypes">[{"name":"Config","definition":" public class Config\r\n {\r\n /* Settings resolved at run time by this configuration Flow.\r\n Consumers in this repository read db_connection_str, to_email\r\n and basic_auth. */\r\n public string login { get; set; }\r\n public string password { get; set; }\r\n public string db_connection_str { get; set; }\r\n public string basic_auth { get; set; }\r\n public string to_email { get; set; }\r\n public string value { get; set; }\r\n public int id { get; set; }\r\n }","isNativeDefinition":true},{"name":"ErrorResponse","definition":"{\r\n \"$schema\": \"http://json-schema.org/draft-06/schema#\",\r\n \"$ref\": \"#/definitions/ErrorResponse\",\r\n \"definitions\": {\r\n \"ErrorResponse\": {\r\n \"type\": \"object\",\r\n \"additionalProperties\": true,\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Data\": {\r\n \"title\": \"The Error Data\",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Data\": {\r\n \"title\": \"The Data Schema\",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"LevelMessage\": {\r\n \"title\": \"The Error level\",\r\n \"type\": \"string\"\r\n },\r\n \"statusCode\": {\r\n \"title\": \"The Error Status Code\",\r\n \"type\": \"integer\"\r\n },\r\n \"ErrNumber\": {\r\n \"title\": \"The Error Number\",\r\n \"type\": \"string\"\r\n },\r\n \"Message\": {\r\n \"title\": \"The Error Message\",\r\n \"type\": \"string\"\r\n },\r\n \"State\": {\r\n \"title\": \"The Error State\",\r\n \"type\": \"string\"\r\n },\r\n \"HelpLink\": {\r\n \"title\": \"The Help Link\",\r\n \"type\": \"string\"\r\n },\r\n \"errNumberReason\": {\r\n \"title\": \"The initial Error Number\",\r\n \"type\": \"string\"\r\n }\r\n }\r\n },\r\n \"ResolveUrl\": {\r\n \"title\": \"The Resolve Url Link\",\r\n \"type\": \"string\"\r\n }\r\n }\r\n },\r\n \"ResolveUrl\": {\r\n \"title\": \"The Resolve Url Link\",\r\n \"type\": \"string\"\r\n },\r\n \"extraData\": {\r\n \"title\": \"The Error Extra Data \",\r\n \"type\": \"object\",\r\n \"properties\": {\r\n \"operationDuration\": {\r\n \"title\": \"The Operation Duration\",\r\n \"type\": \"integer\"\r\n }\r\n }\r\n }\r\n },\r\n \"title\": \"ErrorResponse\"\r\n }\r\n }\r\n}","isNativeDefinition":false},{"name":"SystemException","definition":"{\r\n \"$schema\":\"http://natec.tech/simpleschema\",\r\n \"$ref\":\"#/definitions/SystemException\",\r\n \"definitions\":{\r\n \"SystemException\":{\r\n \"type\":\"object\",\r\n \"properties\":{\r\n \"Exception\":{\r\n \"type\":\"types://core/System.Exception\"\r\n },\r\n \"info\":{\r\n \"type\":\"string\"\r\n }\r\n },\r\n \"title\":\"SystemException\"\r\n }\r\n }\r\n}","isNativeDefinition":false}]</gp:globalParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Populate the newly declared configuration fields

When users import the shipped get-config.bpmn as the documented companion for send-links.bpmn, Activity_GetActivity still initializes only id and value, so the newly declared db_connection_str and to_email properties remain null. The consumer subsequently uses those values for its MSSQL connection and SMTP recipient, causing the example to fail at runtime even after the required companion is imported; initialize these fields with explicit placeholders that users can replace.

Useful? React with 👍 / 👎.

dialexpert and others added 3 commits September 1, 2026 03:40
The repository is public, and the examples carried the addresses of a live one.
Not placeholders — working hosts, an internal database address, and a key.

Removed:

- an API key, 54 characters, in `api-call` since 2024-03-08. Replaced with
  `YOUR_API_KEY`. It has been readable by anyone for two years, so treat it as
  disclosed and rotate it at the source; deleting it here does not remove it
  from the history.
- two compiled assemblies, `api-call.dll` and `api-gateway.dll`. A binary in an
  examples repository teaches nothing and may carry more than its filename
  suggests.

Replaced with local or neutral values:

- hosts `api.wcb.kyivstar.ua`, `api.wcb-tst.kyivstar.ua`,
  `team-api.wcb-tst.kyivstar.ua` -> `localhost`. One of them is production, not
  a test rig.
- the Oracle address `10.49.1.198:1521/bisdb_prm.kyivstar.ua` ->
  `localhost:1521/XEPDB1`, plus eight further internal addresses.
- `Data Source=sqlserv;Initial Catalog=unibill` ->
  `Data Source=localhost;Initial Catalog=examples`; `Password=password` -> empty,
  so nobody inherits a credential that cannot work.
- Postman collections keep the host split into segments, so the string
  replacement missed them; nine host arrays were rebuilt as `["localhost"]`.
- the operator's name where it appeared in sample data and in a variable name.

Left alone: `Natec.Workflow.*` and `natec.tech/simpleschema` are the platform's
own namespace and schema, not a leak.

Verified afterwards: `kyivstar`, `starlink`, `fcs`, `unibill`, `wcb` and
`sqlserv` return nothing across the repository. Two PNG diagrams matched on
bytes; both were opened and show a MEF.DEV architecture picture with no names in
it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The group held fourteen models lifted from running systems. Read as teaching
material they did not work: a newcomer met `sharepoint-get-folders-latest`,
`CredentialSP`, `billCycleNo`, `AgentCard` and a node labelled "to do", and had
to guess which parts were the lesson. One model was a byte-for-byte copy of the
repository's own `http-stream` example. Three referenced a personal library,
which the platform resolves only for the account that created it, so they could
never compile for a reader.

Replaced by nine models, one per group plus the configuration Flow they all
share. Each is generated from the platform's own function catalogue, so no
declaration can drift from the engine, and each was compiled against the
platform before being committed: nine of nine, with the repository's own linter
at zero findings.

What changed in kind, not only in content:

- The code is commented. `#Previous`, `Root.`, `Transition.Counter` and
  `Action.BoundaryEvents` all look like ordinary identifiers and none of them
  are; the comments say so at the point of use.
- Every group README now states the same four things: which capabilities the
  example demonstrates and where to look, which types it declares and how each
  is used, what you actually get back, and why it is built that way.
- The replies in those READMEs were taken from real runs, not written from
  expectation. That is how two facts got recorded that contradict the intent of
  the code: the error branch answers HTTP 200 with a 500 in the body, and the
  event example answers 204 because its second branch finishes last.
- Settings point at two public sources with no key and no account —
  `api.frankfurter.dev` and `jsonplaceholder.typicode.com` — so the examples run
  without a credential to obtain. `login` and `password` stay empty.

Two limits are stated in the READMEs rather than hidden. `AI/Completions` cannot
be called from a model: its body reaches for `Action.BoundaryEvents` and a
cancellation token that are not in scope where the engine inlines it. And a Flow
that calls out needs a stand with a route to the internet; without one it ends
on the error branch, which the streaming README shows as the expected reply.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The catalogue says its data is read from the files, so it was read from the
files again rather than edited by hand. Forty-three models, counted by what each
one actually contains.

The interesting part is what the honest count now shows as uncovered. The models
that were removed were the only ones using an event-based gateway, a signal and
a Data Store, so all three drop to zero, and Sub Process, Multi Instance and the
intermediate events drop to one. Those numbers were previously carried by
material that could not be published; the gap was always there, it was just
filled by something that had to go.

`ExternalAction` remains uncovered, as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dialexpert dialexpert changed the title Flow patterns: publish-ready Teaching examples, and a public repository that no longer carries a live environment Sep 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: faf3b70411

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"body": {
"mode": "raw",
"raw": "{\r\n \"subscriptionId\":[\r\n \"imsi-{{imsi}}\",\r\n \"msisdn-{{msisdn}}\"\r\n ],\r\n \"serviceRating\":[\r\n {\r\n \"userInformation\":{\r\n \"servedPei\":\"imei-{{imei}}\"\r\n },\r\n \"serviceInformation\":{\r\n \"userLocationinfo\":{\r\n \"utraLocation\":{\r\n \"sai\":{\r\n \"sac\":\"acf4\",\r\n \"plmnId\":{\r\n \"mnc\":\"{{mnc}}\",\r\n \"mcc\":\"{{mcc}}\"\r\n },\r\n \"lac\":\"6a33\"\r\n }\r\n }\r\n },\r\n \"sgsnMccMnc\":{\r\n \"mnc\":\"{{mnc}}\",\r\n \"mcc\":\"{{mcc}}\"\r\n },\r\n \"ratType\":\"UTRAN\",\r\n \"pdpAddress\":\"localhost\",\r\n \"chargingCharacteristics\":\"{{schar}}\",\r\n \"apn\":\"{{apn}}\"\r\n },\r\n \"serviceContextId\":\"32251@3gpp.org\",\r\n \"requestSubType\":\"DEBIT\",\r\n \"consumedUnit\":{\r\n \"TotalVolume\":10000\r\n },\r\n \"ratingGroup\":{{rg}}\r\n },\r\n {\r\n \"userInformation\":{\r\n \"servedPei\":\"imei-{{imei}}\"\r\n },\r\n \"serviceInformation\":{\r\n \"userLocationinfo\":{\r\n \"utraLocation\":{\r\n \"sai\":{\r\n \"sac\":\"acf4\",\r\n \"plmnId\":{\r\n \"mnc\":\"{{mnc}}\",\r\n \"mcc\":\"{{mcc}}\"\r\n },\r\n \"lac\":\"6a33\"\r\n }\r\n }\r\n },\r\n \"sgsnMccMnc\":{\r\n \"mnc\":\"{{mnc}}\",\r\n \"mcc\":\"{{mcc}}\"\r\n },\r\n \"ratType\":\"UTRAN\",\r\n \"pdpAddress\":\"localhost\",\r\n \"chargingCharacteristics\":\"{{schar}}\",\r\n \"apn\":\"{{apn}}\"\r\n },\r\n \"serviceContextId\":\"32251@3gpp.org\",\r\n \"requestSubType\":\"RESERVE\",\r\n \"ratingGroup\":{{rg}}\r\n }\r\n ],\r\n \"nfConsumerIdentification\":{\r\n \"nodeFunctionality\":\"OCF\"\r\n },\r\n \"invocationTimeStamp\":\"{{NOW}}\",\r\n \"invocationSequenceNumber\":2\r\n}\r\n ",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep pdpAddress values as valid IP literals

When this Postman request is sent after configuring {{API}}, the payload now supplies "localhost" for pdpAddress; however, the repository's 3GPP-Rf_Rating-v1.1.5.yaml defines that property as an IPv4 or IPv6 string. A schema-validating rating endpoint will therefore reject the request before exercising the intended operation. Use a reserved documentation address such as 192.0.2.1 when anonymizing this field, and update the other newly changed pdpAddress occurrences likewise.

Useful? React with 👍 / 👎.

Comment thread CATALOGUE.md
- Проміжна подія-перехоплювач — 2
- таймер — 1

| `TMF620_Product_Catalog_Management/TMF620_Get_ProductOffering.bpmn` | Exclusive gateway; error; Data Object; Native (C# class); Inner (JSON Schema) | Action | `#Previous`, `#PreviousData`, `Input`, `Logger`, `Parameters`, `WorkflowEnvironment`, `ServiceProvider`, `PassingResult` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include parallel gateways in per-model capabilities

Add Parallel gateway to this model's capability cell: TMF620_Get_ProductOffering.bpmn contains four <parallelGateway> elements (beginning at line 93), but the rebuilt catalogue reports only its exclusive gateway. The same omission affects the other models behind the coverage table's count of 12, so readers cannot use the detailed Models section to find the capability even though the catalogue says its data comes from the files.

Useful? React with 👍 / 👎.

Two things were wrong and neither showed up in a compile.

**The diagrams were unreadable.** The generator places nodes left to right and
puts both data elements at the same point, so `DO_Input` and `DO_Output` sat on
top of each other in every model. Every diagram is now laid out top to bottom:
the main path in one column, each branch leaving a boundary event in a column of
its own to the right, data elements to the left. A Sub Process keeps its own
plane. Checked per plane, ignoring the boundary event that correctly sits on its
task's border: zero overlaps, down from thirteen.

**Two examples do not run, and the READMEs said otherwise.** Every model was
started, not only compiled, and the replies recorded from the runs:

- `raise-event` fails with a `NullReferenceException` inside
  `TransitionBoundaryEvent.Raise`. The engine reads a conveyor branch from an
  `AsyncLocal` that nothing ever assigns — the two lines that would are
  commented out at `WorkflowItemTaskCodeAction.cs:101-103`. So
  `Action.BoundaryEvents[…].Raise(…)` cannot work in this build at all, from any
  diagram. The model is correct and is kept; its README now shows the failure,
  the engine source, and what it will answer once that value is set again.
- `stream-response` was described as failing only for want of network access.
  That is one of two reasons: passing chunks out uses the same `Raise`, so it
  would fail even on a stand that can reach the endpoint.

The earlier README claimed `raise-event` answered 204 because its second branch
finished last. That reading came from the HTTP status alone; the run state says
`Error`. Recorded properly this time, with the run output rather than the
transport code.

The group index now carries the full verification table — every model, its
input, and what it actually returned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b79ed38b26

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +101 to +102
Import `service-config.bpmn` into a tenant library as `flow-patterns-config` and
compile it. Then import `use-config.bpmn` and compile that.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Specify the required tenant library name

When a reader follows these standalone run instructions and imports the companion into a tenant library not named tenant_shared, use-config.bpmn cannot compile because its UsedLibs and Call Activity URI hard-code tenant/tenant_shared/flow-patterns-config. The root README mentions changing that segment, but this group page and the other per-example run sections instruct users to choose any tenant library; either require the tenant_shared library here or tell readers to update each model reference.

Useful? React with 👍 / 👎.

…diagram

The first layout pass understood one shape of branch: the one leaving a boundary
event. Anything else — a second path out of a gateway, a failure handler shared
by two nodes — fell through to the leftover pile and was stacked underneath
everything, hundreds of pixels below the process it belongs to.

Now every unplaced successor of a placed node opens its own column at its
source's row, whatever kind of node the source is. Columns are generated rather
than picked from a fixed list of three, so a model with several branches no
longer crowds them into the last one.

Coordinates only; no model content changed. Still zero overlaps per plane, the
linter reports nothing, and all nine compile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 05ade5c070

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<process id="Process_structured_prompt" name="structured-prompt">
<dataObjectReference id="DO_Input" name="PromptRequest" dataObjectRef="Do_Input" />
<dataObject id="Do_Input" />
<dataObjectReference id="DO_Output" name="PromptRequest" dataObjectRef="Do_Output" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare the prompt array as the process output

Change this output data object to ChatMessage[]: the happy-path task returns List<ChatMessage>, but the end event is associated with a data object declared as the input-only PromptRequest. Consumers inspecting or referencing the compiled Flow therefore receive the wrong output contract even though the runtime value is the two-message array documented in the README.

Useful? React with 👍 / 👎.

<dataObject id="Do_Pages" />
<dataObjectReference id="DO_Input" name="PageRequest" dataObjectRef="Do_Input" />
<dataObject id="Do_Input" />
<dataObjectReference id="DO_Output" name="PageRequest" dataObjectRef="Do_Output" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare the page collection as the process output

Change this output data object to PageInfo[]: after the multi-instance subprocess the model returns a collection of page descriptors, while the end event currently advertises PageRequest, which is only the request containing total. This makes the published output type disagree with both the actual result and the README's documented array.

Useful? React with 👍 / 👎.

The data element carrying the pages now says so twice: `isCollection="true"`,
which is what BPMN reads and what makes a viewer draw the collection marker, and
the `[]` already in its name, which is for the reader and the linter. The two go
together; neither replaces the other.

The README said something stronger and untrue. It claimed the brackets are what
tell the engine the element carries a collection, and that dropping them makes
the Sub Process run once instead of three times. That was inherited lore, and it
does not survive a run: the same model was published three times — with the
brackets alone, with both marks, and with `isCollection` alone — and every
version returned three pages.

What actually drives the iteration is `multiInstanceLoopCharacteristics` on the
Sub Process, over the result it receives. The README now says that, and treats
both marks as documentation of intent rather than mechanism.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3c4f5d0eae

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

<gp:globalParameter name="Functions">[{"name":"RestApi","initCode":"functions://default/RestApi","initParameters":[{"name":"Uri","type":"Uri","required":true,"oldName":"Uri","oldType":"Uri","defaultValue":"http://servername:port/resource"},{"name":"Method","type":"string","required":true,"oldName":"Method","oldType":"string","defaultValue":"GET"},{"name":"Login","type":"string","required":false,"oldName":"Login","oldType":"string","defaultValue":null},{"name":"Password","type":"string","required":false,"oldName":"Password","oldType":"string","defaultValue":null},{"name":"Headers","type":"StringDictionary","required":false,"oldName":"Headers","oldType":"StringDictionary","defaultValue":"{\r\n \"Content-Type\":\"application/json;charset=utf-16\",\r\n \"system\":\"204\",\r\n \"global_unique_id\":\"6a297fcb-956e-4228-8c11-017e9bacd629\"\r\n }"},{"name":"Body","type":"string","required":false,"oldName":"Body","oldType":"string","defaultValue":"{}"},{"name":"Encoding","type":"string","required":false,"oldName":"Encoding","oldType":"string","defaultValue":"utf-8"},{"name":"Timeout","type":"int","required":false,"oldName":"Timeout","oldType":"int","defaultValue":"0"},{"name":"Result","type":"HttpResponse","required":false,"oldName":"Result","oldType":"HttpResponse","defaultValue":null}],"oldName":"RestApi"},{"name":"RestApi/GET","initCode":"functions://default/RestApi/Get","initParameters":[{"name":"Uri","type":"Uri","required":true,"oldName":"Uri","oldType":"Uri","defaultValue":"http://servername:port/resource"},{"name":"Login","type":"string","required":false,"oldName":"Login","oldType":"string","defaultValue":null},{"name":"Password","type":"string","required":false,"oldName":"Password","oldType":"string","defaultValue":null},{"name":"Headers","type":"StringDictionary","required":false,"oldName":"Headers","oldType":"StringDictionary","defaultValue":"{\r\n \"Content-Type\":\"application/json;charset=utf-16\",\r\n \"system\":\"204\",\r\n \"global_unique_id\":\"6a297fcb-956e-4228-8c11-017e9bacd629\"\r\n }"},{"name":"Encoding","type":"string","required":false,"oldName":"Encoding","oldType":"string","defaultValue":"utf-8"},{"name":"Timeout","type":"int","required":false,"oldName":"Timeout","oldType":"int","defaultValue":"0"},{"name":"Result","type":"HttpResponse","required":false,"oldName":"Result","oldType":"HttpResponse","defaultValue":null}],"oldName":"RestApi/GET"},{"name":"JsonPath","initCode":"functions://default//JsonPath","initParameters":[{"name":"Response","type":"HttpResponse","required":true,"oldName":"Response","oldType":"HttpResponse","defaultValue":null},{"name":"Path","type":"string","required":false,"oldName":"Path","oldType":"string","defaultValue":"$"},{"name":"Result","type":"Json","required":false,"oldName":"Result","oldType":"Json","defaultValue":null}],"oldName":"JsonPath"},{"name":"SaveVariable","initCode":"functions://default//SaveVariable","initParameters":[{"name":"VariableName","type":"string","required":true,"oldName":"VariableName","oldType":"string","defaultValue":"varName"},{"name":"Data","type":"object","required":true,"oldName":"Data","oldType":"object","defaultValue":"#previous"}],"oldName":"SaveVariable"},{"name":"SQL/Oracle/Query","initCode":"functions://default//SQL/Oracle/Query","initParameters":[{"name":"userID","type":"string","required":true,"oldName":"userID","oldType":"string","defaultValue":null},{"name":"password","type":"string","required":false,"oldName":"password","oldType":"string","defaultValue":null},{"name":"dataSource","type":"string","required":false,"oldName":"dataSource","oldType":"string","defaultValue":null},{"name":"query","type":"string","required":false,"oldName":"query","oldType":"string","defaultValue":null},{"name":"Result","type":"Collection","required":false,"oldName":"Result","oldType":"Collection","defaultValue":null}],"oldName":"SQL/Oracle/Query"},{"name":"SQL/Oracle/Command","initCode":"functions://default//SQL/Oracle/Command","initParameters":[{"name":"userID","type":"string","required":true,"oldName":"userID","oldType":"string","defaultValue":null},{"name":"password","type":"string","required":false,"oldName":"password","oldType":"string","defaultValue":null},{"name":"dataSource","type":"string","required":false,"oldName":"dataSource","oldType":"string","defaultValue":null},{"name":"command","type":"string","required":false,"oldName":"command","oldType":"string","defaultValue":null},{"name":"Result","type":"int","required":false,"oldName":"Result","oldType":"int","defaultValue":null}],"oldName":"SQL/Oracle/Command"}]</gp:globalParameter>
<gp:globalParameter name="ExternalDefinitionLib">[]</gp:globalParameter>
<gp:globalParameter name="Parameters">[{"name":"dbConnectionString ","type":"string","initialValue":"host=192.168.25.204;port=5432;Database=catalyst_hw;User Id=postgres;password=example;"},{"name":"di","type":"DiagnoseIncident","initialValue":""},{"name":"HuaweiApiHost","type":"string","initialValue":"http://185.190.206.134:8484"},{"name":"InfosysApiHost","type":"string","initialValue":""},{"name":"llamaBearer","type":"string","initialValue":"LL-OlLPN1yRufuR3uEXRnTZkbHjBaC7NMq3o4wwobAGIJbUyeSQ13mcn0Bak3yUqwKG"},{"name":"QvantelApiHost","type":"string","initialValue":""},{"name":"textEmbeddingUrl","type":"string","initialValue":"http://192.168.25.204:5000"},{"name":"TroubleTicket","type":"Json","initialValue":""},{"name":"listOfAlarms","type":"string[]","initialValue":""}]</gp:globalParameter>
<gp:globalParameter name="Parameters">[{"name":"dbConnectionString ","type":"string","initialValue":"host=localhost;port=5432;Database=catalyst_hw;User Id=postgres;password=example;"},{"name":"di","type":"DiagnoseIncident","initialValue":""},{"name":"HuaweiApiHost","type":"string","initialValue":"http://localhost:8484"},{"name":"InfosysApiHost","type":"string","initialValue":""},{"name":"llamaBearer","type":"string","initialValue":"LL-OlLPN1yRufuR3uEXRnTZkbHjBaC7NMq3o4wwobAGIJbUyeSQ13mcn0Bak3yUqwKG"},{"name":"QvantelApiHost","type":"string","initialValue":""},{"name":"textEmbeddingUrl","type":"string","initialValue":"http://localhost:5000"},{"name":"TroubleTicket","type":"Json","initialValue":""},{"name":"listOfAlarms","type":"string[]","initialValue":""}]</gp:globalParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the remaining Llama bearer token

The sanitization rewrites the database and service hosts in this parameter bundle but leaves a credential-shaped llamaBearer value intact; Activity_0ueq4ev sends it as a bearer token to the public api.llama-api.com endpoint. Anyone with repository access can recover and potentially spend against that credential, so replace it with a placeholder and rotate/revoke the exposed token.

Useful? React with 👍 / 👎.

<incoming>Fl_007</incoming>
<property id="Prop_Ev_Failed" name="__targetRef_placeholder" />
<dataInputAssociation id="Dia_Ev_Failed">
<sourceRef>DO_Output</sourceRef>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare the error response on the failing end event

When validation fails for an empty orderId, HandleException returns an ErrorResponse, but this failed end event is associated with DO_Output, which is declared as OrderRequest. The published process contract therefore describes the failure body as an order even though the documented and runtime value is the error object; give the failure branch its own ErrorResponse data object.

Useful? React with 👍 / 👎.

<process id="Process_stream_response" name="stream-response">
<dataObjectReference id="DO_Input" name="StreamRequest" dataObjectRef="Do_Input" />
<dataObject id="Do_Input" />
<dataObjectReference id="DO_Output" name="StreamRequest" dataObjectRef="Do_Output" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the nonexistent stream response body

After all chunks are raised, T_Stream explicitly returns null, and the README says the chunks themselves are the result, but the successful end event still advertises StreamRequest through this output data object. API consumers and generated metadata will consequently expect a request-shaped response body that this flow never produces; model the success path as no-body output instead.

Useful? React with 👍 / 👎.

`Action.BoundaryEvents[…].Raise(…)` was described as broken outright. It is
broken only on builds carrying a regression that lasted from 9 January 2026 to
2 September 2026 — the assignment of `BoundaryEvents.ConveyorBranch` was
commented out in `WorkflowItemTaskCodeAction.cs` and has now been restored.

A stand with the fix runs `raise-event` to `Completed`; one without it still
answers `Error` with a `NullReferenceException` inside `Raise`. Both were
observed today on two different stands, which is why the README now names the
symptom to look for rather than declaring the capability dead.

The index table keeps the two failing rows, because the stand these results were
measured on has not been updated yet — but it now says that is what it is.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

https://github.com/mef-dev/bpmn-examples/blob/7c6df2e0589bd810386be81a8ba043153d192243/tmforum-apis/TMF640_Service_Activation_and_Configuration/TMF640_Service_Activation.postman_collection.json#L460
P1 Badge Remove the remaining Basic authentication credentials

The host for this request was sanitized to localhost, but its Authorization value remains a Base64-encoded username/password pair rather than a placeholder. The same problem occurs in the changed 3GPP and TMF688 collections, with another credential pair, so repository readers can recover credentials for the original endpoints from these directly executable requests; replace every encoded value (including copies in request descriptions and saved responses) and rotate the exposed credentials.



P2 Badge Sanitize the structured URL host as well

Changing only raw leaves this request's structured host set to 185.190.206.134 (and the saved original request has the same mismatch). The collection therefore still publishes the supposedly removed live address and contains two conflicting representations of its destination; replace the host array with localhost wherever this URL appears.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…o source

The platform already carries request and response examples into the generated
Swagger, and it pairs them by name: `StartSignalRoute.examples` is a dictionary
keyed by example name, `EndSignalRoute.exampelsVariants` is a list keyed by
`title`. A name present on one side and not the other silently produces a
request example with no matching response.

Every end event in this group now carries one named example, and the values are
what these models actually returned when run, not invented ones. Where a Flow
declares an HTTP route, the request example names match the response names
exactly.

Each process also gains a one-line English description and a link back to its
folder in this repository, so a reader who meets the model inside a generated
specification can find the source it came from.

Two details of the platform's shape, both learned the hard way:

- the key is spelled `exampelsVariants`, not `examplesVariants`;
- `value` is a JSON **string** on both sides. Passing an object fails the parse
  with `Unexpected character encountered while parsing value: {`.

`producedTypeVariants` names the declared type each end event returns —
the flow's own type on success, `ErrorResponse` on the failure branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fad4e4dc5a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

{
"key": "Authorization",
"value": "Basic YXBpX3VzZXI6V2lkZWNvdXAx"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the remaining Basic credential

This Base64 value decodes to a username/password pair and is still sent in the collection's Authorization headers whenever a user configures {{API}}; the same credential also remains throughout the modified TMF688 collection and its generated cURL descriptions. Because this change is intended to remove live-environment material from a public repository, replace every occurrence with a placeholder and rotate the exposed credential.

Useful? React with 👍 / 👎.

</task>
<task id="T_Plan" name="plan the pages">
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType": "Expression", "action": "// The page size is a setting, not a constant: it belongs in the\n// configuration Flow so every consumer agrees on it.\nvar size = Parameters.config.pageSize;\n\n// This step only plans. Building the list first, and walking it\n// second, is what lets the Sub Process run the pages in parallel.\nvar pages = new List&lt;PageInfo&gt;();\nfor (int start = 0; start &lt; Input.total; start += size)\n pages.Add(new PageInfo() { number = pages.Count + 1, startIndex = start, size = size });\n\nLogger.LogInformation($\"{Input.total} rows split into {pages.Count} pages of {size}\");\nreturn pages;"}</ep:elementParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Cap the final page at the remaining row count

When Input.total is not divisible by pageSize (including the documented total=25, pageSize=10 example), every PageInfo receives size = size, so the final descriptor incorrectly reports 10 rows rather than the remaining 5. This contradicts the documented short final page and misleads consumers that use the returned descriptors; set the per-page size to the minimum of the configured size and Input.total - start.

Useful? React with 👍 / 👎.

… per outcome

Three things were missing from the routes, and all three show up in the
generated specification rather than in the model.

**Headers.** Every end event now declares the set every operation returns:
`Accept` and `Content-Type` as `application/json;charset=utf-8`,
`Accept-Language`, and `x-ms-client-request-id`. A `PATCH` operation takes
`application/json-patch+json` instead; the pass reads the method from the start
route and picks accordingly.

**Formatting.** Example bodies were single-line strings. They are still strings —
the platform requires that — but the JSON inside is indented, so the designer's
example box can be read without horizontal scrolling.

**One request per outcome.** Every response name carried the *same* request
body, which explains nothing: three identical examples do not tell a reader what
produces a timeout rather than a success. A request example is now given only
where it genuinely differs, and a response with no request pair is allowed —
not every outcome is caused by the input.

The checker gained the rule that catches this: two example names carrying the
same request body is a defect, and so is an example body that names an HTTP code
other than the one its end event declares.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

https://github.com/mef-dev/bpmn-examples/blob/75e647a32e8ecde6644aa7428e43795e94ed6917/tmforum-apis/TMF640_Service_Activation_and_Configuration/TMF640_Service_Activation.postman_collection.json#L460
P1 Badge Remove the remaining TMF640 Basic credential

The collection sanitizes its service endpoints to localhost but still sends this credential-shaped Basic value; Base64-decoding it yields the username/password pair fcs_user:getYfZy*LKYP, and the value is repeated in other request and generated-cURL headers in this file. Anyone with repository access can recover and potentially use the credential, so replace every occurrence with a placeholder and rotate/revoke it.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

dialexpert and others added 2 commits September 2, 2026 16:27
An example with an empty summary and no description tells a reader nothing
about why it is there. Each request example now says what it is in one line
and what comes back in another.

Also corrects the configuration Flow's own description. It said settings live
there "so no consuming Flow knows its environment", which describes a
consequence rather than the thing; it now says it holds the settings the rest
of the group reads.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The platform compiles a model with overlapping shapes, arrows ending in empty
space and silently skipped nodes exactly as happily as a clean one, and the
editor says nothing. These scripts are the warning that is missing.

  tools/verify.py          runs every check over every example, non-zero exit
                           on any violation, ready for CI
  tools/checks/            eleven readability rules, five rules about request
                           and response examples, plus edge, graph, label,
                           inline-size and overlap checks
  tools/layout/            the transformation passes: top-to-bottom layout,
                           orthogonal routes, label and comment placement,
                           association ends, type-to-data-object binding,
                           Code Action argument binding
  tools/platform/          fetch the generated C# for a published model, so an
                           engine error is read from the code it actually ran
                           rather than guessed from element names

Two of these earned their place the hard way. Among tasks the engine executes
only task and serviceTask; scriptTask, businessRuleTask, userTask, manualTask,
sendTask and receiveTask compile without a warning and are then skipped, so the
flow returns whatever the previous node produced and looks like it passed. And a
Code Action argument written as Input.x arrives as the literal string "Input.x";
only #Input.x and {Input.x} pass a value, and for a non-string parameter the
node dies with no error at all.

Running verify.py over the nine examples reports 27 violations of rules 2, 6
and 7 — the rules were written after the examples and have not been applied back
to them yet. Left visible on purpose rather than silenced.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c16ed86cb5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tools/verify.py
Comment on lines +69 to +73
output = (proc.stdout or "") + (proc.stderr or "")
failures = len(VERDICT.findall(output))
for pattern in COUNTED:
failures += sum(int(n) for n in pattern.findall(output))
return failures, output

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Treat checker process failures as verification failures

When any checker crashes—for example because a BPMN file is malformed—its traceback contains none of the parsed verdict strings, so failures remains zero and verify.py exits successfully. I confirmed that python tools/verify.py /tmp/bad.bpmn reports violations: 0 and exits 0 for invalid XML; incorporate proc.returncode into the result so CI cannot approve files that were never checked.

Useful? React with 👍 / 👎.

Comment on lines +181 to +187
has_input_example = any("{" in (a.findtext("{*}text") or "") for a in annotations)
print(f"\n7. Приклад входу в коментарі: {'є' if has_input_example else 'немає'}")
print(" " + ("ОК" if has_input_example else "ПОРУШЕНО"))

# 11 — межа процесу вже оголошує тип, а gateway його не змінює: другий такий
# самий аркуш поруч із задачею нічого не додає, лише змушує звіряти два.
from rule_redundant_dor import redundant_data_objects # noqa: E402

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the shipped examples satisfy the enforced annotation rules

When the documented no-argument command is run against this commit, all nine replacement models contain no textAnnotation elements, so these two unconditional checks alone produce 18 violations; missing association edges add another nine, and python tools/verify.py exits 1 with 27 total violations. Either add the required annotations and diagram edges to the examples or adjust the rules, otherwise the newly advertised CI command fails on the repository it is meant to validate.

Useful? React with 👍 / 👎.

Comment thread tools/layout/relayout.py
Comment on lines +154 to +161
for fid, src, dst in self.flows:
if src not in self.pos or dst not in self.pos:
continue
sx, sy, sw, sh = self.pos[src]
tx, ty, tw, th = self.pos[dst]
start = (sx + sw // 2, sy + sh)
end = (tx + tw // 2, ty)
lines.append(f' <bpmndi:BPMNEdge id="Ed_{fid}" bpmnElement="{fid}">')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve non-sequence diagram elements during relayout

When relayout.py is run on a model containing data associations or text annotations, render() emits edges only from self.flows, which contains only sequenceFlow entries, while annotations are also absent from the supported node tags. The semantic XML survives but its association edges and annotation shapes disappear from the regenerated diagram; I reproduced this with TMF640_Patch_Service.bpmn. Preserve or regenerate those shapes and edges before replacing the entire BPMNDiagram section.

Useful? React with 👍 / 👎.

It shipped with one model's comments baked into it — a JSON example and three
paragraphs keyed by annotation id — so running it on any other model silently
replaced that model's comments with those. A pass that rewrites content is not a
layout pass.

It now reads each textAnnotation, re-wraps prose to the requested width, leaves
a structured block (JSON, lists) with its own line breaks because there every
line carries meaning, and fits the frame to the result. What the comment says
stays the model's business.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

https://github.com/mef-dev/bpmn-examples/blob/7e736565a904ba7b8bdaf49565871d02b95e6f0f/tmforum-apis/TMF640_Service_Activation_and_Configuration/TMF640_Service_Activation.postman_collection.json#L460
P1 Badge Remove the remaining TMF640 Basic credential

This value decodes to the username/password pair fcs_user:getYfZy*LKYP and is sent in the request whenever a user configures {{API}}; the same credential also remains in saved requests and the generated cURL description later in this modified collection. Because this change sanitizes environment-specific material for publication, replace every occurrence with a placeholder and rotate the credential if it is still valid.


text = re.sub(rf'\s*<data(?:Input|Output)Association id="{assoc}">.*?'
r"</data(?:Input|Output)Association>", lambda m: "", text, flags=re.S)
text = re.sub(rf'\s*<dataObjectReference id="{ref}"[^>]*/>', lambda m: "", text)
if obj:
text = re.sub(rf'\s*<dataObject id="{obj}" ?/>', lambda m: "", text)

P1 Badge Preserve data objects still used by process boundaries

When a task and its downstream end event share the same data object reference, the redundancy detector marks the task association as removable, but this unconditional deletion removes the shared reference and underlying dataObject while leaving the end event's sourceRef pointing to the deleted ID. Running this transformation on that valid, common arrangement therefore produces a dangling boundary association and an invalid model; exclude references used by boundary events or remove only a genuinely separate duplicate.


for fid, (src, dst) in flows.items():
for end, kind in ((src, "outgoing"), (dst, "incoming")):
el = next((e for e in root.iter() if e.get("id") == end), None)
if el is None:
print(f" потік {fid}: вузол {end} не існує")
bad += 1
elif not any((r.text or "").strip() == fid
for r in el.findall(f"{{*}}{kind}")):

P2 Badge Detect missing BPMN diagram shapes and edges

When the semantic incoming/outgoing declarations are consistent but a BPMNShape or sequence-flow BPMNEdge is absent, this reverse pass reports zero discrepancies because it only searches semantic elements and never reads the diagram interchange section. The other checks also iterate only diagram elements that already exist, so verify.py can approve a model whose nodes or arrows are invisible despite claiming to verify that every flow has an edge and every node a shape.


ROUTES = {
# гілка відмови входить у кінцеву подію знизу, двома прямими
"Flow_13s4qsf": [(1670, 400), (1740, 400), (1740, 58)],
# елемент даних стоїть рівно над своєю задачею
"Doa_Response": [(920, 110), (920, 70)],
}
for eid, points in ROUTES.items():

P2 Badge Orthogonalize arbitrary routes instead of two fixed IDs

When straighten.py is run on any model whose diagonal edge is not named Flow_13s4qsf or Doa_Response, this loop makes no route change at all and the later scan merely reports the skew. That contradicts the documented generic command that accepts a model path and “makes routes orthogonal”; derive replacement waypoints from each detected diagonal rather than hard-coding identifiers and coordinates from one model.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…side it

A model nobody can regenerate can only be edited by hand, and that is how the
file and the intent drift apart. Each example now carries <name>.spec.json: what
it takes in, what each step does and why, what it answers with, and the types it
needs. The model is what the tools make of that.

  python tools/build.py        rebuilds all nine
  python tools/verify.py       checks without rebuilding

All nine were regenerated this way. verify: 0 violations. Compiled against the
platform: 9/9.

Four passes are new. split_shared_data gives each end event its own data
element, so success and failure no longer share one and their arrows no longer
cross. add_types carries the types, external types and libraries a step needs
beyond its own input and output. add_examples writes the process documentation
with the link back to source and the response example on each end event.
add_notes places the comments and the input example the specification declares.

snap_associations now draws an association that has no edge at all - until now a
data element could sit on the diagram with nothing leading to it - routes it
orthogonally, and treats captions and already-drawn lines as obstacles.
place_data_labels no longer dodges lines: the caption is anchored under its own
shape and the lines route around it.

Two specifications sit in flow-patterns/parked with no model. They wait on the
platform: AI/Completions callable from a model, IO/Local/Archive exposed to
flows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58073fc654

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

</task>
<task id="T_Work" name="do the work in parts">
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType": "Expression", "action": "// A long step does not have to stay silent until it ends. Raising the\n// boundary event lets a second branch report progress while this one\n// keeps working — the event is non-interrupting.\nfor (int part = 1; part &lt;= 3; part++)\n{\n Logger.LogInformation($\"part {part} done\");\n\n // The name in brackets is the id of the boundary event on the\n // diagram. Get it wrong and the engine raises BoundaryEventNotFound.\n Action.BoundaryEvents[\"Event_Progress\"].Raise($\"part {part} of 3\");\n}\nreturn new JobRequest() { jobId = Input.jobId };"}</ep:elementParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the boundary event targeted by the progress raiser

Every run that reaches T_Work attempts to raise Event_Progress, but the model declares only the unrelated Ev_Err_T_ParseConfig boundary event and contains no reporting branch. Consequently the first loop iteration cannot emit progress and instead hits the missing-boundary failure described by this example's own README; add the non-interrupting Event_Progress boundary event and its T_Report route.

Useful? React with 👍 / 👎.

</task>
<task id="T_Stream" name="read the stream line by line">
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType": "Expression", "action": "// #Previous.Reader is the open response body. Reading it line by line\n// keeps memory flat no matter how long the answer turns out to be.\nstring line;\nwhile ((line = #Previous.Reader.ReadLine()) != null)\n{\n if (string.IsNullOrWhiteSpace(line))\n continue;\n\n // Each line leaves through the boundary event, so the caller sees\n // the answer arriving instead of waiting for all of it.\n Action.BoundaryEvents[\"Event_Chunk\"].Raise(line);\n}\n\n// The stream itself is the result; there is nothing left to return.\nreturn null;"}</ep:elementParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add the boundary event that delivers stream chunks

When the upstream endpoint returns any nonblank line, T_Stream raises Event_Chunk, but no such boundary event or chunk-handling branch exists anywhere in this model (its only boundaries handle errors from config parsing and T_Call). Thus a reachable endpoint makes the advertised streaming path fail on the first chunk rather than forwarding it; add the non-interrupting event and delivery branch referenced by the code.

Useful? React with 👍 / 👎.

<sequenceFlow id="Fl_001" sourceRef="Ev_Start" targetRef="CA_Config" />
<sequenceFlow id="Fl_002" sourceRef="CA_Config" targetRef="T_ParseConfig" />
<sequenceFlow id="Fl_003" sourceRef="T_ParseConfig" targetRef="T_Plan" />
<sequenceFlow id="Fl_004" sourceRef="T_Plan" targetRef="Ev_End" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route planned pages through the multi-instance subprocess

For every successful request, Fl_004 sends the result of T_Plan directly to Ev_End; the model contains neither a subProcess nor multiInstanceLoopCharacteristics. Therefore none of the documented per-page work runs, no page URLs are logged, and this cannot demonstrate the Sub Process/Multi Instance capability attributed to it in the README and catalogue.

Useful? React with 👍 / 👎.

Comment on lines +20 to +24
<startEvent id="Ev_Start" name="">
<outgoing>Fl_001</outgoing>
<dataOutputAssociation id="Doa_Input">
<targetRef>DO_Input</targetRef>
</dataOutputAssociation>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Declare the advertised HTTP route on the start event

The newly added Ev_Start has only its outgoing flow and data association; there is no StartSignalRoute element parameter anywhere in the model. Publishing it therefore cannot claim the documented POST /webhook route, so the central trigger example remains startable only through the ordinary Flow endpoints until the route configuration is added.

Useful? React with 👍 / 👎.

Running each example against the platform on its own published input found three
things a compiler cannot see.

Two examples raised a boundary event that was not in the model at all. They
compiled and failed on the first run. The event a step raises is now declared in
the specification beside it and built by add_boundary_event.

A REST step without Headers throws ArgumentNullException before the call is
made, and an Accept carrying a charset is rejected as a malformed header.

The rates source no longer answers, so the configuration points at one that
does. The copy published in the tenant library still carries the old address
until someone republishes it.

  verify:   9 models, 0 violations
  compile:  9/9
  run:      9/9 answer with real data

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@dialexpert dialexpert changed the title Teaching examples, and a public repository that no longer carries a live environment Teaching examples that run, each built from the specification beside it Sep 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 78a7b54c21

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +36 to +38
for fid, (src, dst) in flows.items():
for end, kind in ((src, "outgoing"), (dst, "incoming")):
el = next((e for e in root.iter() if e.get("id") == end), None)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Compare sequence flows with diagram edges

When a semantic sequenceFlow has no corresponding BPMNEdge, this loop verifies only its incoming/outgoing declarations and never inspects the diagram, while check_edges.py examines only edges that already exist. Removing Ed_Fl_001 from first-flow.bpmn still lets python tools/verify.py report zero violations and exit successfully, so CI can approve a diagram with an invisible process arrow; compare the semantic flow IDs against the diagram edge IDs here.

Useful? React with 👍 / 👎.

Comment on lines +78 to +81
if outcomes:
text = re.sub(
r'<ep:elementParameter name="EndSignalRoute">(.*?)</ep:elementParameter>',
fill, text, flags=re.S)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Create metadata for ends without EndSignalRoute

When bpmn_forge leaves the ordinary 200 end without an EndSignalRoute, this substitution visits only the existing 500 route. That is the shape of all eight new generated consumer models: each has two end events but only one route, so success outcomes such as GREETED are never written into the BPMN despite being present in the specification and advertised as response examples. Add route metadata for unmatched end events rather than only editing routes that already exist.

Useful? React with 👍 / 👎.

Сховища даних були єдиною можливістю, якої генератор не вмів, тому весь
файловий клас прикладів лишався поза досяжністю. add_stores.py будує їх із
блоку `stores` і привʼязує кожне до кроку, який ним користується: рушій
показує кроку лише привʼязані сховища, решта компілюється і не існує.

09 - Files створює теку, пише в неї файл, пакує його і відповідає посиланням
на завантаження. Перевірено на стенді: HTTP 200 і живе посилання.

Три обмеження записані там, де вони болять, а не списком: `object` сховища
береться дослівно, запис не створює відсутніх тек, а AddFolderToZip
недосяжний, бо System.IO.Compression не входить у посилання компілятора
потоків.

Спробу викликати AI/Completions відкладено: її тіло вживає CT і
Action.BoundaryEvents, а в контексті вузла-задачі немає ні того, ні того.

README приведені до фактів: `Raise` уже працює, і там же ціна одного підйому.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 12182450be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +43 to +46
elif el.get("name") == "EndSignalRoute":
titles = [v.get("title") for v in (data.get("exampelsVariants") or [])
if isinstance(v, dict) and v.get("title")]
ends.append((data.get("code"), titles, data.get("producedTypeVariants")))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Count end events that lack route metadata

When an end event has no EndSignalRoute, this loop never adds it to ends, so the checker reports zero missing examples. I confirmed this on first-flow.bpmn: it contains two semantic end events but only one route, while check_examples.py prints кінцевих подій без прикладу: 0; consequently the advertised verification command cannot detect the missing success metadata in the shipped models.

Useful? React with 👍 / 👎.

</startEvent>
<task id="T_GetConfig" name="resolve the settings">
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType": "Expression", "action": "return new Config()\n{\n ratesUrl = \"https://open.er-api.com/v6\",\n listUrl = \"https://jsonplaceholder.typicode.com/posts\",\n login = \"\",\n password = \"\",\n pageSize = 10\n};"}</ep:elementParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return the endpoint documented by the companion flow

When users import this shipped configuration and run use-config.bpmn with the documented { "key": "EUR" }, T_UseConfig appends /latest?base=EUR to this value and returns https://open.er-api.com/v6/latest?base=EUR, not the documented/specification result https://api.frankfurter.dev/v1/latest?base=EUR. Align this setting with the companion README and success example so the teaching flow produces its promised output.

Useful? React with 👍 / 👎.

Comment on lines +60 to +62
<task id="T_Archive" name="pack it and issue a link">
<extensionElements>
<ep:elementParameter name="ElementImplementation">{"actionType": "Expression", "action": "// AddToZip answers with the archive as a file of its own.\nLocalFile archive = DataAssociations.DS_File.GetFile().AddToZip(\"archive.zip\");\n\n// The link carries its own authorisation: whoever receives it\n// needs no session of yours to fetch the archive.\nreturn new ArchiveResult() { folder = \"flow-patterns/archive-demo\", url = archive.CreateLink() };"}</ep:elementParameter>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route archive-step failures to the error outcome

When GetFile(), AddToZip(), or CreateLink() throws, this task has no attached boundary error; the only operational boundary is attached to the preceding T_Write, so it cannot catch failures here. The run therefore terminates as an engine error instead of reaching T_HandleException and returning the advertised ARCHIVE_FAILED response; T_Folder has the same gap for folder-store failures.

Useful? React with 👍 / 👎.

Три з пʼяти помилок тієї компіляції були мої:

  CS0246  тип аргументу генерується без простору імен, тож зовнішній тип
          оголошено під тим самим іменем, а не під коротшим псевдонімом;
  CS1061  JSON не динамічний обʼєкт - зміст дістається через Cast<T> у
          оголошений тип, тому додано AiChunk, AiChoice і AiDelta;
  CS0266  оголошений масив стає List<> у згенерованому методі, а #Previous
          приходить як object.

Останнє довелося міряти: приведення префіксом ламає розбір, бо # мусить бути
першим символом виразу, і компілятор читає його як директиву препроцесора
(CS1040). Працює форма з as.

Лишаються дві помилки з тіла самої вбудованої функції - CT і
Action.BoundaryEvents. Їх закриває PR 4758; після розгортання цей приклад і
буде його перевіркою.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant