ADR-040 — Process I/O: объявленный контракт вызываемого¶
| Поле | Значение |
|---|---|
| Статус | Принято |
| Версия | v.2 |
| Дата | 2026-08-27 (v.1 принята 2026-08-26; v.2 принята 2026-08-27) |
| Владелец | Руслан Габитов |
| Уточняет | ADR-011 v.9 §2.5 (запланированный путь данных Start/End уровня процесса — это решение поставляет его половину-носитель), ADR-023 v.4 (прямое отображение I/O у Call Activity — это решение даёт сторону вызываемого, которую тот называет), SAD-001 v.1.2 §14.1 (отклонение single-set и тождество ioBinding; оба здесь расширяются) |
EN-оригинал — канонический: ADR-040-process-io-contract.md. Этот файл — его перевод (twin).
Область решения. BPMN
Process— этоCallableElementи может объявлятьInputOutputSpecification— входы и выходы данных уровня процесса, объявленный контракт процесса как вызываемой сущности. Это решение определяет, чем этот контракт является для движка: носитель в модели, когда и как связываются входы и читаются выходы, что проверяет граница вызова и что означает процесс без контракта. Это та самая возможность модели, которую ADR-024 v.6 §2.16 регистрирует для<ioSpecification>на<process>(#330); по его второму правилу — возможность приземляется раньше потребляющей её строки — она приземляется собственным решением — этим документом; реализацию описывает сопутствующий SRD. v.2 закрывает то единственное, что v.1 отложила: проводку через ассоциации событий той же концепции — особый случай Start/End стандарта — и момент, когда запуск, рождённый событием, заполняет контракт (§2.7).
1. Контекст¶
1.1 Что объявляет стандарт¶
Только «Tasks and CallableElements (Processes, GlobalTasks)» могут
определять DataInputs/DataOutputs — через их InputOutputSpecification
(§10.4.1 стр. 210 — правило вложенности, которое импортёр уже обеспечивает
для всего остального). Спецификация агрегирует контракт: упорядоченные
dataInputs и dataOutputs, где пустой набор означает «no data required
to start» / «to finish» (§10.4.1); она «MUST have at least one
InputSet» (§10.4.1 стр. 217).
Назначение формы уровня процесса названо прямо, и это вызов: «To allow invoking a Process from both a Call Activity and via Message Flow» (§10.4.2) стандарт делает DataInputs объемлющего Process доступными как цели выходных ассоциаций данных Start Event, а его DataOutputs — как источники входных ассоциаций данных End Event. А для самого вызова ассоциации не нужны вовсе: у Call Activity «DataInputs / DataOutputs are mapped to corresponding elements in the CallableElement without any explicit DataAssociation» (§10.4.1 стр. 216).
1.2 Где стоит движок¶
ADR-011 v.9 §2.5 запланировал ровно это: особый случай Start/End уровня процесса — «часть концепции; приземляется вместе с работами по messaging/call-activity, которым он нужен». Работа по call activity с тех пор приземлилась — и её решение уже говорит языком стандарта: ADR-023 v.4 предписывает, что входы Call Activity «отображаются на InputOutputSpecification вызываемого»: входы связываются в корневую область дочернего при запуске, выходы связываются обратно при завершении.
Но у вызываемого нет InputOutputSpecification, на которую можно отобразить.
Контракт реализован односторонне: объявленные имена параметров
вызывающего решают, что входит в дочерний процесс и что читается назад,
вызываемый не объявляет ничего, и ничто не проверяет границу — неверно
названный или отсутствующий вход всплывает как сбой разрешения данных глубоко
внутри работающего дочернего процесса, далеко от места вызова. У хоста,
запускающего процесс напрямую, тот же пробел в обе стороны: ни объявленной
полезной нагрузки запуска, ни объявленного результата. А импортёр отвергает
легальный <ioSpecification> на <process> — зарегистрированная блокировка
по возможности (ADR-024 v.6
§2.16, #330).
2. Решение¶
2.1 Process объявляет single-set I/O-контракт¶
Process модели получает необязательную I/O-спецификацию: один входной
набор и один выходной набор именованных, типизированных, обязательных или
необязательных параметров — то же понятие параметра, которое уже используют
его активности. Форма single-set — это действующее отклонение
SAD-001 v.1.2 §14.1 (несколько
наборов с выбором по данным — решённая не-реализация), распространённое на
вызываемого, где оно действует с большей силой, а не меньшей: стандарт
требует хотя бы одного InputSet (§10.4.1 стр. 217), а движок держит ровно
один. Порядок сохраняется (наборы в стандарте упорядочены); различие
обязательный/необязательный живёт внутри набора, как ADR-011 его уже
держит.
2.2 Входы — поверхность запуска¶
Объявленные входы процесса связываются в корневую область экземпляра при запуске, каким бы ни был вход:
- Call Activity связывает их из собственных объявленных входов — прямое отображение §10.4.1 стр. 216, у которого наконец есть сторона вызываемого, на которую отображать;
- запуск хостом подаёт их напрямую с запросом старта — тот же контракт, минус вызывающая диаграмма.
Обязательный вход, не связанный при запуске, отказывает в запуске, называя вход — никогда не ожидание. Это распространяет зарегистрированное отклонение движка «нет ожидания данных» (SAD-001 v.1.2 §14.1) на инстанциацию: запуск, который сидел бы до появления данных, — скрытая синхронизация, а у вызывающего, который не может подать обязательный вход, проблема в диаграмме, о которой движок должен сказать вслух на границе, а не застрявшим экземпляром. Размещение в корневой области означает, что входы видны каждой дочерней области через обычный подъём вверх — ровно как свойства.
2.3 Выходы — поверхность завершения¶
Объявленные выходы процесса читаются из корневой области экземпляра при нормальном завершении:
- Call Activity фиксирует их в область вызывающего под его собственными объявленными именами выходов (то же прямое отображение, наружу);
- запуск хостом получает их как объявленный результат завершённого экземпляра.
Обязательный выход, недоступный при нормальном завершении, переводит экземпляр в fault — процесс заявил результат, которого не произвёл, и молчаливое завершение без него вручило бы вызывающему дыру там, где контракт обещал значение. Необязательный выход просто не передаётся. При терминальном fault или termination не читается ничего: у ненормального конца нет поверхности результата.
2.3a Что может нести выход и как значение туда попадает¶
Объявленный параметр — именованный, типизированный item-aware элемент, поэтому границу может пересечь всё, что выражает семейство значений модели: скаляр, запись, список, отображение (структурные данные ADR-011 v.9), включая значения, поднятые из host-native структур через ярус адаптеров.
Публикация — это обычная механика копирования; ничего нового данные не двигает. Объявленный выход — это датум под своим именем, живущий в корневой области, а данные корневой области — то, на что уже нацелены существующие ассоциации данных:
- результат активности публикуется её выходной ассоциацией, нацеленной на выход процесса — общий случай;
- значение объекта данных или свойства публикуется тем же способом — копируется наружу активностью, которая его касается;
- входные ассоциации End Event — выделенная точка сбора стандарта (§10.4.2), проводка по §2.7; копии посреди потока служат ничуть не хуже, и они конформны: путь §10.4.2 доступен, а не исключителен.
Runtime-переменные движка публикуются отображением, никогда объявлением.
STARTED_AT, STATE, TRACKS_CNT, COMPLETED_BY живут под
зарезервированным именованным источником RUNTIME, доступным только для
чтения (ADR-010 v.2 §2.7): это чтения по
пути (RUNTIME/STARTED_AT), а не данные области, поэтому они никогда не
могут быть выходом — выход есть данные области, которыми владеет
экземпляр. Поверхности результата они достигают теми же двумя путями,
которыми достигают чего угодно:
- отображение берёт источником чтение по квалифицированному пути —
входная ассоциация задачи читает
RUNTIME/STARTED_AT(единый шов чтения §2.7), а выходная ассоциация задачи фиксирует значение дальше: в объект данных или прямо в выход процесса; - Go-операция внутри процесса читает их через свой read-only reader данных (SAD-001 v.1.2 §14.2) и возвращает как свой объявленный выход.
В любом случае опубликованное значение — копия, зафиксированная в названный момент потока, что и есть правило §2.3a в общем виде: ассоциации данных стандарта копируют (собственный язык §10.4.2; позднее изменение источника не распространяется), поэтому поверхность результата держит зафиксированные значения, а не живые представления.
Исключено из публикации, каждое по названной причине: хранилище данных — глобальный для движка порт (ADR-030 v.1), разделяемый между экземплярами, а не результат экземпляра; локальные данные дочерней области — данные под-процесса умирают вместе с его областью, поэтому значение, которое должно её пережить, копируется наружу до закрытия области (существующее правило областей, без изменений); и алиасинг — объявление выхода, который является свойством или объектом данных и заполняется неявно. Алиасинг сделал бы результат живым представлением внутреннего состояния, привязал бы публичный контракт к внутреннему имени и противоречил бы семантике копирования выше; явная копия держит «что возвращает этот процесс» видимым на диаграмме — тот же принцип видимости, что у отклонения «нет ожидания данных».
2.4 Граница вызова сопоставляется по имени и проверяется при запуске¶
Стандарт отображает обе стороны «to corresponding elements» без явных ассоциаций (§10.4.1 стр. 216), и вендоренный экстракт читает это соответствие как позиционное. Заметка движка: этот движок сопоставляет по имени и фиксирует расхождение. Имена — то, как эта модель адресует данные везде: свойства, параметры, поиск в областях, — тогда как позиционное соответствие привязывает смысл вызова к порядку объявления на обеих сторонах, и невинная перестановка молча перепроводит данные: ровно тот класс тихой поломки, ради прекращения которого объявленный контракт и существует. ADR-023 v.4 уже формулировал связывание как «позиционное/по имени»; это решение закрепляет его за именем.
Проверка происходит при запуске, а не при регистрации, потому что раньше она произойти не может: ADR-019 v.1 привязывает вызов к последней версии вызываемого на момент запуска (если не закреплена), так что контракт вызываемого не зафиксирован до самого момента вызова. При запуске, до того как дочерний процесс побежит: каждому обязательному входу вызываемого должен соответствовать вход вызывающего с тем же именем; каждый выход вызывающего должен называть объявленный выход вызываемого. Несовпадение отказывает в запуске на Call Activity — fault в месте вызова, перехватываемый там же, — а не сбоем разрешения глубоко в дочернем процессе.
При ровно одном наборе с каждой стороны тождество ioBinding из
SAD-001 v.1.2 §14.1 переносится без
изменений: выбирать нечего, поэтому связывание и есть соответствие имён.
2.5 Вызываемый без контракта сохраняет разрешительный смысл¶
Процесс, который не объявляет I/O-спецификацию, означает то, что означают пустые наборы стандарта — «no data required to start», ничего не обещано к завершению (§10.4.1), — и движок добавляет разрешительное чтение, которое путь вызова имел всегда: он принимает всё, что объявленные входы его вызывающего доставляют в его корневую область, и возвращает всё, что объявленные выходы вызывающего у него просят. Именно объявление контракта делает границу обязывающей. Это сохраняет валидность каждого существующего процесса и вызова и делает строгость opt-in вызываемого — стороны, чей это интерфейс.
2.6 Свойства и I/O остаются различными¶
Свойство — это внутреннее состояние процесса: объявлено со своим item и начальным значением, рождается при инстанциации. Вход — это приходящее чужое значение; выход — уходящее значение. И то и другое живёт в корневой области и адресуется по имени, поэтому их держит одно пространство имён — объявленный вход, совпадающий с именем свойства, есть ошибка валидации при регистрации, а не правило затенения. Никакого неявного моста: свойство не заполняется из одноимённого входа, и выход не читает свойство, если собственный поток процесса не положил значение туда.
2.7 Проводка через события: параметры процесса — концы ассоциаций¶
Особый случай Start/End стандарта (§10.4.2 стр. 224) существует, «чтобы
позволить вызывать Process как из Call Activity, так и через Message
Flow»: выходные ассоциации Start Event могут быть нацелены на
DataInput'ы объемлющего процесса, входные ассоциации End Event могут
брать источником его DataOutput'ы. Он течёт через ассоциации данных
событий, семантику которых уже задаёт
ADR-011 v.9 §2.5 — входные ассоциации
throw-события заполняют его входы при срабатывании, выходные ассоциации
catch-события проталкивают данные триггерящего элемента наружу, никогда не
ожидая, — и которые возможность прикрепления (строка
ADR-024 v.6 §2.16) делает
достижимыми: catch-событие есть источник ассоциации над своими выходами
данных, throw-событие — цель ассоциации над своими входами данных,
каждый выход/вход данных объявлен по одному на несущее item определение, в
порядке определений, с item'ом определения (стр. 217). Это решение
определяет сторону процесса в этой проводке:
- Объявленный вход процесса — законная цель выходной ассоциации Start Event, объявленный выход процесса — законный источник входной ассоциации End Event — и только для собственных Start- и End-событий процесса, двух позиций, которые называет стандарт. Конец на стороне процесса — сам объявленный параметр; его имя есть его имя в корневой области (§2.2, §2.3), так что копия ложится туда, где контракт читает.
- Запуск, рождённый событием, заполняет контракт через выходные ассоциации родившего старта — на посеве, до связывания контракта. Движок никогда не исполняет родивший старт как узел (он уже сработал); момент, когда его ассоциации могут выполниться, — тот единственный, которым §2.9 уже владеет: после фиксации полезной нагрузки в корневую область, до проверки объявленных входов. Обязательный вход, который заполнило сообщение, связывается как поставленный хостом; всё ещё не связанный отказывает в запуске, как говорит §2.2, — ждать никакой возможности больше не нужно.
- Путь копирования — маршрутизируемый через область (ADR-030 v.1 §2.3): ассоциация — это маршрут, который исполняющийся экземпляр читает, чтобы найти датум своего экземпляра по имени; ни один объект модели не меняется во время выполнения. То же правило, которому уже подчиняется каждая задача, теперь инвариант движка и для событий.
- Заметки движка. Выход или вход данных, которому не соответствует ни
одно определение, отвергается при построении: стандарт заполняет выходы
события триггерящим элементом и ничем иным, так что параметр, который
ничто не заполняет, — ошибка моделирования, а не константа (константа —
это свойство). Концы-свойства у ассоциаций событий остаются отдельно
зарегистрированной возможностью (строка
Associate*-на-Propertyв §2.16); пока она не приземлилась, ассоциация события нацелена на объект данных, хранилище данных или параметр процесса.
Прямые пути §2.2/§2.3 остаются механизмом маршрута вызова, без каких-либо ассоциаций, ровно как у стандарта; маршрут по Message Flow теперь достигает того же контракта через описанную выше проводку.
2.8 Конвертер следует за моделью¶
Как только носитель существует, <ioSpecification> на <process> (и его
голые входы/выходы данных) отображается — разбирается в контракт
процесса, — потребляя строку реестра #330 по
ADR-024 v.6 §2.16. Импортёр
продолжает отвергать то, чему это решение не даёт дома: несколько входных
или выходных наборов остаются действующей multi-set границей
(SAD-001 v.1.2 §14.1),
сформулированной как выбор, а не как расписание.
2.9 Прогон, момент за моментом¶
Контракт касается жизни экземпляра ровно в двух моментах и невидим между ними:
- Регистрация проверяет объявление: единое пространство имён (§2.6), собственную корректность спецификации. Снимок несёт контракт как объявление, разделяемое всеми экземплярами этой версии.
- Запуск, до появления какого-либо токена. Всё, что доставил вход — объявленные входы вызывающего, запрос старта хоста, — связывается через объявленные входные параметры (§2.2): каждый объявленный вход берёт значение из доставленного датума своего имени, с проверкой типа по объявлению; обязательный вход без датума или доставленный датум, не называющий ни одного объявленного входа, отказывают в запуске. После отказа экземпляра не существует — ни цикла, ни трека, нечего подчищать. Запуск, рождённый событием, проходит то же связывание — после того как выходные ассоциации родившего старта скопировали полезную нагрузку в объявленные входы, на которые нацелены (§2.7), — так что обязательный вход, который заполнило сообщение, связывается, а тот, который ничто не заполнило, отказывает, теми же словами.
- Прогон. Связанные входы — обычные данные корневой области, читаемые по имени из каждого фрейма и каждой дочерней области, ровно как свойства. Объявленный выход — слот корневой области, который поток заполняет обычной механикой копирования (§2.3a). Ни одно решение движка не читает контракт, пока движутся токены: ни планировщик, ни шлюзы, ни гейты ассоциаций данных. Checkpoint, restore, дегидратация и гидратация переносят связанные данные как данные корневой области, которыми они и являются, и никогда не связывают заново.
- Нормальное завершение, после того как закончился последний токен. Объявленные выходы читаются из корневой области и копируются в результат экземпляра (§2.3); обязательный выход, отсутствующий или недоступный, переводит экземпляр в fault в этот момент — форма терминального fault, которая у движка уже есть, поэтому вызывающий получает fault на своей Call Activity, а хост получает ошибку из своего ожидания, без поверхности результата в обоих случаях. Ненормальный конец до этого шага никогда не доходит.
- Возврат. Результат течёт к тому, кто запускал: фиксируется в область вызывающего под объявленными именами выходов вызывающего (соответствие имён §2.4, проверенное при запуске вызова) либо открывается хосту как объявленный результат завершённого экземпляра.
Процесс без контракта пропускает моменты 2 и 4 целиком и бежит, как бежал всегда (§2.5).
3. Последствия¶
- Контракт вызова становится двусторонним. «Отображаются на InputOutputSpecification вызываемого» из ADR-023 перестаёт быть пожеланием: вызываемый объявляет, а сломанный вызов падает на границе вызова при запуске с несовпавшим именем в руках — не сбоем поиска в области где-то внутри дочернего процесса.
- Хост получает объявленную поверхность запуска и результата. Старт процесса принимает проверенную полезную нагрузку; завершённый экземпляр отдаёт объявленный результат — больше никакого результата-по-соглашению через свойства.
- Легальный файл загружается. Переиспользуемый вызываемый процесс
моделиста — форма, объявляющая
<ioSpecification>на<process>, — перестаёт отвергаться; строка реестра #330 потреблена. - Половина Message Flow остаётся запланированной, видимо. Заполнение входов процесса из полезной нагрузки message-старта требует возможности прикрепления к событиям; §2.7 фиксирует, где этот долг оплачивается.
- Ничто по-прежнему не ждёт данных. Отклонение «нет ожидания данных» теперь покрывает инстанциацию и завершение наряду с активностями — одно правило, три момента.
4. Рассмотренные альтернативы¶
Свойства как поверхность I/O (без нового носителя; вызывающие заполняют
свойства по соглашению). Отклонено — это слабость статус-кво, получившая
имя: у свойства нет направления, нет обязательности, а его жизненный цикл —
внутреннее состояние, поэтому «контракт» остаётся тем, что угадывает
вызывающий, и ничто не может проверить границу. Стандарт тоже держит
Property и DataInput/DataOutput как различные виды элементов с
различной вложенностью (§10.4.1).
Проверка границы вызова при регистрации. Отклонено — её нельзя выполнить честно: ADR-019 v.1 разрешает вызываемого при запуске (последняя-на-момент-запуска, если не закреплена), поэтому проверка при регистрации либо навязывает раннюю привязку версии, либо проверяет по версии, которую вызов может не использовать. Момент запуска — когда контракт реален.
Позиционное соответствие на границе вызова (чтение §10.4.1 стр. 216 в вендоренном экстракте). Отклонено как правило этого движка, расхождение зафиксировано в §2.4: позиция привязывает смысл вызова к порядку объявления на обеих сторонах, и невинная перестановка молча перепроводит данные. Имена — схема адресации модели везде в остальном.
Ожидание опоздавшего входа при запуске (ожидание доступности данных, редакция для процесса). Отклонено — тот же аргумент о скрытой синхронизации, что и у зарегистрированного отклонения SAD-001 v.1.2 §14.1; процесс, которому нужно приостановиться ради данных, моделирует это catch-событием, видимо.
Несколько входных/выходных наборов на Process. Отклонено без нового аргумента — действующее отклонение §14.1; модель устроена так, что выбор multi-set мог бы вернуться как расширение, если появится реальный спрос.
5. Открытые вопросы¶
Нет. Единственная отсрочка v.1 — проводка через ассоциации событий — решена в §2.7 (v.2); оставшаяся граница, выбор multi-set, — действующая (§2.8), а не отсрочка.
6. Ссылки¶
- ADR-011 v.9 §2.5 — запланированная концепция, для которой это решение поставляет носитель.
- ADR-023 v.4 — контракт вызова, сторону вызываемого которого это решение даёт.
- ADR-019 v.1 — последняя-на-момент-запуска, что фиксирует момент проверки (§2.4).
- ADR-024 v.6 §2.16 — строка реестра #330, которую это решение потребляет, и строка attachment API, через которую проводка §2.7 достигает контракта.
- ADR-030 v.1 §2.3 — путь копирования через область, который §2.7 делает инвариантом для событий.
- SAD-001 v.1.2 §14.1 — отклонения single-set и «нет ожидания данных», которые это решение расширяет.
- ADR-010 v.2 §2.7 — именованный
источник
RUNTIME, через чьи чтения по пути публикуют отображения §2.3a. - ADR-030 v.1 — глобальное для движка хранилище данных, которое §2.3a исключает из поверхности результата.
- semantics/data.md — вендоренный экстракт, несущий каждое процитированное выше положение §10.4.1/§10.4.2 (вложенность стр. 210, прямое отображение вызова стр. 216, InputSet MUST стр. 217, особый случай Start/End процесса).
История документа¶
| Версия | Дата | Автор | Изменения |
|---|---|---|---|
| v.1 | 2026-08-26 | Руслан Габитов | Первоначальное решение. Process получает single-set I/O-контракт (отклонение SAD-001 §14.1, распространённое на вызываемого): именованные, типизированные, обязательные или необязательные параметры. Входы связываются в корневую область при запуске — из объявленных входов Call Activity (прямое отображение §10.4.1 стр. 216, наконец со стороной вызываемого) или из запроса старта хоста; обязательный вход, не связанный при запуске, отказывает в запуске, никогда не ждёт. Выходы читаются из корневой области при нормальном завершении — фиксируются вызывающему или отдаются хосту; обязательный выход, недоступный при завершении, переводит экземпляр в fault; у ненормальных концов нет поверхности результата. Соответствие на границе вызова — по имени (заметка движка — стандарт правила не формулирует) и проверяется при запуске (последняя-на-момент-запуска из ADR-019 делает более раннюю проверку невозможной). Процесс, объявляющий отсутствие контракта, сохраняет разрешительный смысл — строгость есть opt-in вызываемого. Свойства остаются различными (одно пространство имён, никакого неявного моста; совпадение имён отвергается при регистрации). §2.3a инвентаризирует пути публикации — обычную механику копирования (выходные ассоциации активностей; значения объектов данных/свойств через копии; сбор End Event, как только приземлится возможность прикрепления), runtime-переменные, публикуемые только отображением read-only чтений RUNTIME/… (ADR-010 v.2 §2.7) через ассоциации задачи или reader Go-операции (никогда не объявляются выходами — они не данные области), и исключения: хранилища данных (глобальные для движка), локальные данные дочерней области (копируются наружу до закрытия области) и алиасинг (выход — зафиксированная копия, никогда не живое представление — собственная семантика копирования стандарта). Проводка через ассоциации событий отложена до возможности прикрепления (§2.7); конвертер отображает <ioSpecification> на <process>, как только приземлится носитель, потребляя строку реестра #330. §2.9 фиксирует форму прогона: контракт касается экземпляра ровно в двух моментах — запуск (до любого токена) и нормальное завершение (после последнего) — и невидим для каждого решения движка между ними; отказ при запуске не оставляет экземпляра, а ненормальный конец никогда не доходит до шага результата. Принято 2026-08-26 — приземлено целиком через SRD-093 (носитель, привязка при запуске, чтение при завершении, проверка границы вызова, строка импортёра, examples/process-io/); в приземление вошли итоги аудита и независимого ревью (непроизведённый необязательный выход не течёт к вызывающему; выходы привязываются через своё объявление, так что несовпадение типа даёт fault; явная пустая <ioSpecification/> — строгий пустой контракт). Флип статуса; ссылка на реестр переехала вместе с выводом ADR-038 в ADR-024 v.6 §2.16. RU twin создан. |
| v.2 | 2026-08-27 | Руслан Габитов | §2.7 решён вместо отсрочки: особый случай Start/End стандарта достигает контракта через ассоциации данных событий — объявленный вход процесса есть цель выходных ассоциаций его Start Event, объявленный выход — источник входных ассоциаций его End Event; запуск, рождённый событием, заполняет контракт через ассоциации родившего старта на посеве, до проверки входов (пункт 2 §2.9 переформулирован); путь копирования событий — маршрутизируемый через область (ADR-030 §2.3) как инвариант; выход/вход данных без парного определения отвергается (заметка движка). Маршрут по Message Flow теперь достигает того же контракта, который маршрут вызова связывает напрямую. Без изменений в §2.1–§2.6, §2.8. Принято 2026-08-27 — приземлено целиком через SRD-094 (события как концы ассоциаций, WithDataOutputs/WithDataInputs, общий путь копирования через область, Process.AssociateInput/AssociateOutput, прогон ассоциаций родившего старта на посеве с записями в Data Store, отложенными до принятия контракта, импортёр, examples/event-data/); в приземление вошли итоги независимого ревью (концы процесса адресуют параметр события по id; импортёр сверяет itemSubjectRef'ы файла друг с другом). ADR-011 перепривязан к v.9 (его §2.5 теперь указывает сюда). |