Контроль кооперативных стандартов (workflow): capital #79

Merged
ant merged 16 commits from feat/coop-standards-audit into marketplace2 2026-06-05 11:01:36 +00:00
Owner

Контроль кооперативных стандартов (workflow coop-standards-check, агенты на Opus)

Сквозной аудит всех 15 .standard.yaml: сверка с кодом + человеческий бизнес-язык прозы. Правки консервативные — техно-хвосты убраны из прозы (идентификаторы кошельков/операций, Gateway, ledger2, enum-имена счетов/кошельков), путаница счёт ≠ кошелёк устранена; structured-поля (Дт/Кт, кошельки, ledger_code, имена экшнов) не тронуты. Спорный дрейф с кодом (возможные баги, семантика статусов) НЕ правил — вынесено в блоки «⚠️ На ревью».

Контрактов: 6, стандартов: 15.


Контракт capital — стандартов 4

p.cap.debt.standard.yaml — Выдача займа пайщику

Выдача займа пайщику

Кооператив выдаёт пайщику беспроцентный целевой заём из паевого фонда на срок проекта. Возврат — автоматически при сдаче акта приёма-передачи проекта (отдельная заявка на возврат не нужна).

1. Последовательность действий

  1. Пайщик подаёт заявление на заём → заявка зарегистрирована, под неё резервируется часть доступного пайщику лимита.
  2. Председатель добавляет документ-одобрение → «Председатель одобрил».
  3. Совет авторизует выплату → «Совет авторизовал»: заём считается выданным, кассир получает поручение на выплату.
  4. Кассир подтверждает зачисление займа на банковский счёт пайщика → «Заём выплачен» (финал).

Отказ: председатель/совет отклоняет на шагах 2–3 (лимит возвращается, движений денег нет); платёжная система не провела выплату на шаге 4 (заявка аннулируется).

2. Проводки

Когда Дт Кт Смысл
Выплата займа (кассир подтвердил, шаг 4) 58 «Финансовые вложения» 51 «Расчётный счёт» деньги ушли пайщику, у кооператива учтены как финансовое вложение
Возврат по акту-2 (RID-flow*) 80 «Паевой фонд» 58 «Финансовые вложения» вложение закрывается, сумма зачитывается в паевой фонд пайщика

* Возврат (o.cap.repay) фактически относится к процессу РИД (акт-2), а не к процессу долга — см. unresolved.

3. Документы

Шаг Документ Подписывает
1 Заявление на получение займа пайщик
2 Решение о предоставлении займа (одобрение) председатель
3 Решение о предоставлении займа (авторизация) совет

4. Движение по кошелькам

  • Выдача (шаг 4): заём фиксируется на кошельке «Выданные пайщикам беспроцентные займы» — обязательство пайщика перед кооперативом.
  • Резерв (шаг 1): под заявку блокируется часть доступного пайщику лимита; при отказе — освобождается.
  • Возврат (акт-2): сумма переводится с кошелька выданных займов на паевой кошелёк пайщика (доступный остаток паевых взносов).

Счёт ≠ кошелёк: «расчётный счёт 51» и «банковский счёт пайщика» — бухгалтерские/банковские счета; кошельки — учётный слой движения средств кооператива.

⚠️ На ревью (НЕ правил):

  • КРИТИЧНО (autofixable=false, семантика): операция o.cap.repay (triggered_by capital::debtpaycnfrm) по реестру кода принадлежит process_type p.cap.rid, а не p.cap.debt — REPAY проводится в RID-flow (signact2/акт-2), а debtpaycnfrm.cpp вызывает только LEND. Возможно, операцию o.cap.repay следует целиком убрать из стандарта долга. Не трогал — требует решения ревьюера/проверки кода, не механический фикс.
  • INFO (не расхождение): documents registry_id 1050/1051 — папки реестра существуют, но в .cpp процесса долга нет Document::validate_registry_id(1050/1051); привязка id↔код не enforced контрактом (createdebt использует verify_document_or_fail без проверки registry_id). Информативно.
  • SOFT (стиль, не применял): в operations[o.cap.lend]/[o.cap.repay].description проводки Дт58/Кт51 и Дт80/Кт58 в прозе дублируют L1-бухслой — можно опустить, оставив бизнес-смысл. Оставлено как есть (бухгалтер их понимает, §6 допускает Дт/Кт).
  • SOFT (стиль, не применял): inline-комментарий wallet_to:w.wal.share «ЦПП Цифровой Кошелёк — паевые взносы деньгами» можно сократить до «паевой кошелёк пайщика».

p.cap.invest.standard.yaml — Приём инвестиции в программу

Приём инвестиции в программу («Благорост»)

Пайщик переводит часть своих свободных паевых средств в инвестицию в программу «Благорост». Деньги физически остаются на расчётном счёте кооператива — меняется только то, как они учитываются у пайщика. Процесс одношаговый.

1. Последовательность действий

  1. Пайщик → подписывает заявление об инвестировании в «Благорост» и подаёт его (действие capital::createpinv).
  2. Контракт → проверяет: пайщик активен, средств достаточно, заявление не дубль и подписано; переводит указанную сумму в инвестицию и фиксирует факт в учёте.

Итоговое состояние: Инвестировано (финальное).

2. Проводки

Бухгалтерских проводок нет. Дебет/кредит не задаются (оба пустые). Средства не покидают паевой фонд и не меняют бухгалтерский счёт — это перенос внутри фонда. Для бухгалтера: счёт 80 (паевой фонд) не затрагивается, деньги остаются на расчётном счёте кооператива.

3. Документы

  • Заявление об инвестировании денежных средств в «Благорост» — подписывает пайщик (Участник) ЭЦП на шаге 1.

4. Движение по кошелькам

  • Откуда: свободные паевые средства пайщика.
  • Куда: инвестиция пайщика в программу «Благорост».
  • Что блокируется: инвестированная сумма перестаёт быть свободной — после перевода пайщик может участвовать в проектах программы как исполнитель.

⚠️ На ревью (НЕ правил):

  • guard «уникальность invest_hash» (findings, autofixable=false): в createpinv.cpp нет явной проверки уникальности invest_hash; историческая таблица progrinvests @deprecated, createpinv в неё не пишет. Возможна неявная идемпотентность через operation_id в Ledger2::apply, но в самом экшне guard не реализован. Текст guard смягчён до «не повторяет ранее поданное», но фактическое наличие защиты надо подтвердить на ревью (или удалить guard, если защиты нет).
  • operations[0].human_name (soft): «Инвестиция в ЦПП «Благорост» (перенос между кошельками)» — рекомендация заменить уточнение в скобках на «(перенос внутри паевого фонда пайщика)» либо опустить как техническое. Не применял (soft).
  • scenario.steps[0].post[2] (soft): «Создана запись инвестиции в таблице» — рекомендация «Факт инвестиции зафиксирован в учёте пайщика». Не применял (soft).
  • post[0] и post[1] после правки звучат близко по смыслу (оба про зачисление суммы в инвестицию) — на ревью решить, не объединить ли их в один пункт.

p.cap.prop.standard.yaml — Приём имущественного паевого взноса

Приём имущественного паевого взноса

Пайщик передаёт кооперативу имущество (не деньги, не РИД) как паевой взнос в программу «Благорост».

1. Последовательность действий

  1. Пайщик подаёт предложение о внесении имущества (описание + сумма оценки) — предложение зарегистрировано.
  2. Председатель одобряет предложение.
  3. Совет авторизует приём имущества.
  4. Пайщик ставит первую подпись на акте приёма-передачи (передаёт имущество).
  5. Председатель ставит вторую подпись на акте — завершающее действие: имущество зачислено пайщику как паевой взнос.

Ветка отказа: председатель или совет отклоняет предложение (шаги 1–3) — запись удаляется, имущество как паевой взнос не зачисляется.

2. Проводки

Когда Дт Кт Смысл
Вторая подпись председателя (шаг 5) 4 — Нематериальные активы 80 — Паевой фонд (складочный капитал) Кооператив принял имущество (по сумме оценки), оно учтено как часть паевого фонда

Единственная проводка во всём процессе — на завершающей подписи. До неё движений по учёту нет.

3. Документы

Шаг Документ Подписывает
1 Заявление об инвестировании имущества в благорост Пайщик
3 Решение совета об инвестировании имущества Совет
4 Акт приёма-передачи (первая подпись) Пайщик
5 Акт приёма-передачи (вторая подпись) Пайщик + Председатель

На ревью: привязка документов к конкретным реестровым папкам в коде не проверяется; акт «первая/вторая подпись» в коде хранится в одном поле, а не в двух.

4. Движение по кошелькам

  • На завершающей подписи имущество (по сумме оценки) зачисляется пайщику в кошелёк программы «Благорост» как паевой взнос. Внешнего источника нет — это выпуск (зачисление) на сумму оценки.
  • До завершающей подписи и при отказе — никакого движения средств не происходит.

⚠️ На ревью (НЕ правил):

  • [document, warning, autofixable=false] Ни один .cpp pgprp не вызывает Document::validate_registry_id — только verify_document_or_fail. Соответствие registry_id (1070→statement, 1071→authorization, 1072→act1/act2) в стандарте — допущение, не закреплённое и не верифицируемое контрактом. Решить на ревью: оставить как документную привязку или пометить как недоказанную.
  • [document, info, autofixable=false] Стандарт описывает два документа на registry_id 1072 (act1/act2) со stored_in pgproperties.act1 и pgproperties.act2, но в таблице program_property только одно поле act (document2); act1pgprp и act2pgprp пишут в одно поле. Полей act1/act2 в коде нет — расхождение модели документов.
  • [guard, soft] transitions[∅→created].guards[0] «Пайщик имеет статус active» → предложено «Пайщик состоит в кооперативе и активен» (не применял — soft).
  • [scenario, soft] scenario.steps[1].description содержит «property_hash» и technical-формулировку → предложено упростить (не применял — soft).
  • Замечание по коду (вне scope правки): комментарий в act2pgprp.cpp:47 ошибочно пишет «Dr 51», тогда как фактическая проводка из реестра = счёт 4. Стоит поправить комментарий в коде отдельно.

p.cap.rid.standard.yaml — Приём результата интеллектуальной деятельности

Приём результата интеллектуальной деятельности (p.cap.rid)

Участник программы «Благорост» оформляет результат своей работы (РИД) как имущественный паевой взнос, а в конце распределяет полученный взнос между своим Цифровым Кошельком и программой.

1. Последовательность действий

  1. Участник создаёт коммит РИД по проекту.
  2. Мастер проекта одобряет коммит (либо отклоняет — тогда запись удаляется).
  3. Участник после завершения проекта подаёт заявление о результате.
  4. Председатель одобряет заявление.
  5. Совет авторизует приём РИД (либо отклоняет на любой стадии — возврат к повторной подаче).
  6. Участник ставит первую подпись на акте приёма-передачи.
  7. Председатель ставит вторую подпись — РИД принят, при наличии займа он закрывается.
  8. Участник распределяет паевой взнос между Цифровым Кошельком и программой «Благорост» — процесс завершён.

2. Проводки

  • Шаг 2 (одобрение коммита): Дт 8 (вложения во внеоборотные активы) / Кт 80 (паевой фонд) — РИД зачислен в паевой фонд участника.
  • Шаг 7 (приём по акту): Дт 4 (нематериальные активы) / Кт 8 — РИД принят в НМА на полную стоимость результата.
  • Шаг 7 (опционально, заём): Дт 80 (паевой фонд) / Кт 58 (финансовые вложения) — закрытие беспроцентного займа участника, сумма высвобождается на его паевом взносе.
  • Шаг 8 (распределение): новых проводок нет — бухгалтерская запись уже сделана при приёме РИД в НМА; это только перераспределение средств участника.

3. Документы

  • Заявление о взносе РИД — подписывает участник (шаг 3), затем председатель добавляет подпись при одобрении (шаг 4).
  • Протокол решения совета о приёме паевого взноса РИД — совет (шаг 5).
  • Акт приёма-передачи РИД — первая подпись участника (шаг 6), вторая подпись председателя (шаг 7).
  • Заявление о распределении паевого взноса — участник (шаг 8).

4. Движение средств участника

  • При одобрении коммита РИД зачисляется в паевой фонд участника (по программе «Благорост»).
  • При приёме по акту движения средств участника не происходит — приём идёт только в бухучёте; накопленный взнос остаётся неразделённым.
  • При наличии беспроцентного займа проекта он закрывается, высвобожденная сумма становится доступной на паевом взносе участника.
  • В финале участник распределяет паевой взнос: часть — в Цифровой Кошелёк, часть остаётся в программе «Благорост» (любая из частей может быть нулевой).

⚠️ На ревью (НЕ правил):

  • [info, autofixable=false] Ни один .cpp процесса p.cap.rid не вызывает Document::validate_registry_id — привязка документа к registry_id не enforced on-chain (только verify_document_or_fail по подписи). Соответствие id берётся из комментариев/папок реестра. На ревью подтвердить, что 1040/1041/1042/1080 корректны методологически.
  • [info, autofixable=false] Имена состояний в стандарте — нарративные вехи (commit_created/approved/pushed/...), а не литеральные C++ Status-константы (Results::Status{CREATED,APPROVED,AUTHORIZED,ACT1,ACT2,DECLINED}; Segments::Status{...,CONTRIBUTED}). Расхождения нет, но при желании можно добавить маппинг нарратив→константа в комментарии.
  • [soft] Шапка «Источники правды в коде» (строки 15-19) — технические ссылки на .cpp/.hpp избыточны для читателя-бухгалтера; допустимо вынести в служебный блок или удалить, и убрать перечисление имён o.cap.* . Не применял (soft).
  • [soft] guards и inline debit-комментарии с registry_id=1040/1041/1042 и «Дт 4 / Кт 8 уже сделана в o.cap.accept» (строки 542, 556) — soft, оставлены: убрать ссылку на имя операции из debit-комментария («бухгалтерская запись сделана при приёме РИД в нематериальные активы») и упростить guards (registry_id, rfrshsegment, intellectual_cost) на ревью.
  • [soft] operations[o.cap.repay].description содержит номера счетов в прозе (Кт 58 / Дт 80) — финдинг предлагает убрать перечисление номеров из прозы (они уже в полях debit/credit). Не применял (soft).

Контракт marketplace — стандартов 3

p.mkt.return.standard.yaml — Гарантийный возврат имущества

Гарантийный возврат имущества

Заказчик в пределах гарантийного срока возвращает имущество на склад участка и получает обратно сумму заказа.

1. Последовательность действий

  1. Заказчик подаёт заявление на гарантийный возврат — указывает причину (некондиция, истёк срок годности, иное), прикладывает фото товара, ссылается на акт приёма-передачи. Только пока не истёк гарантийный срок поставщика.
  2. Председатель участка рассматривает заявление удалённо (по фото и описанию) и решает: пригласить на очный визит или отказать удалённо.
  3. Если визит одобрен — заказчик приходит на участок с продукцией, председатель очно осматривает товар и выносит финальное решение: принять возврат или отказать на месте.
  4. При принятии возврата товар остаётся на складе участка, сумма заказа возвращается заказчику. При отказе (удалённо или очно) — процесс завершён, движений по имуществу и средствам нет.

2. Проводки (только при принятии возврата)

  • Дт 10 «Материалы» / Кт 86 «Целевое финансирование» — имущество возвращается на склад участка за счёт целевого финансирования (зеркало выдачи).

3. Документы

  • Заявление пайщика на гарантийный возврат имущества (с фото) — подписывает заказчик на шаге 1.
  • Решение председателя о принятии возврата — подписывает председатель на шаге 3 (специализированный шаблон в реестре пока не заведён — см. unresolved).
  • Отказы (удалённый / очный) фиксируются в системе как процедурное решение, отдельным документом в MVP не оформляются.

4. Движение по кошелькам

  • При принятии возврата заказчику восстанавливается сумма заказа на его программном членском кошельке «Стола заказов» (зеркально ранее списанной при выдаче).
  • Средства остаются в программе: заказчик направляет их на следующие заказы либо отдельным действием выводит в универсальный членский кошелёк.
  • Ничего не блокируется; при отказе движений по кошелькам нет.

⚠️ На ревью (НЕ правил):

  • Дрейф documents[].accretrn registry_id=0 (autofixable=false): папки 0.* в реестре нет (placeholder), реальный документ «Решение председателя КУ» не существует; в коде accretrn привязки registry_id нет, decision верифицируется только по подписи. Нужен специализированный шаблон в registry либо in-system запись — решение методолога, не автофикс.
  • Дрейф documents[].submretrn registry_id=800 (autofixable=false): папка 800.ReturnByAssetStatement существует, но submretrn.cpp НЕ вызывает validate_registry_id(statement,800) и не verify_document_or_fail для statement — привязка декларирована только в YAML. Плюс по памяти проекта registry_id=800 = старый клиринговый контур, не членская модель. Требует решения: либо завести новый registry_id рядом с актами/ТТН, либо подтвердить привязку в коде.
  • soft operations[0].human_name «Гарантийный возврат — восстановление средств и имущества» — рядом ISSUE/debit/credit (structured), human_name человечный; помечен soft для единообразия, не трогал.
  • soft inline-комментарий строки 323-324 (маркер L1): «# L1 — двойная запись: имущество возвращается на склад через целевое финансирование» — по сути бизнесовый, но содержит маркер уровня L1; оставлен как soft на ревью.

p.mkt.supply.standard.yaml — Прямая поставка-приобретение имущества

Прямая поставка-приобретение имущества (Стол заказов)

1. Последовательность действий

  1. Заказчик размещает заказ (товар, количество, пункт выдачи на участке). Средства резервируются под заказ.
  2. Служба кооператива закрывает цикл сбора заявок: если набран минимальный порог — заказы объединяются в одну заявку поставщику; если нет — все заказы отменяются, резерв снимается.
  3. Поставщик акцептует консолидированную заявку (или отказывается — тогда заказы отменяются).
  4. Поставщик собирает партию точно по составу заявки и выбирает доставку (самовывоз / экспедитор).
  5. Поставщик передаёт партию на участок и ставит первую подпись на акте приёмки.
  6. Председатель ставит вторую подпись — поставка принята, имущество на складе, возникает обязательство оплатить поставщику.
    • 6a. Кооператив инициирует выплату; у кассира появляется задача провести банковский перевод.
    • 6b. Кассир подтверждает перевод (или отклоняет) — обязательство закрывается (остаётся открытым при отказе).
  7. Председатель открывает выдачу.
  8. Заказчик забирает имущество, ставит финальную подпись. При расхождении факт/заказ сумма заранее корректируется. Заказ закрыт, открыто гарантийное окно.

2. Проводки (Дт/Кт)

  • Создание заказа — Дт 80 (Паевой фонд) / Кт 86 (Целевое финансирование): резерв средств под заказ.
  • Отмена / недовыдача — без проводки (движение внутри счёта 86).
  • Доплата по факту — Дт 80 / Кт 86: доп. паевой взнос переходит в целевое финансирование.
  • Приёмка имущества (вторая подпись председателя) — Дт 10 (Материалы) / Кт 86.
  • Оплата поставщику (после подтверждения кассиром) — Дт 86 / Кт 51 (Расчётный счёт).
  • Выдача имущества (финальная подпись заказчика) — Дт 86 / Кт 10.

3. Документы

  • Акт приёма-передачи (приёмка кооперативом) — две подписи: поставщик (передал), затем председатель (принял). Шаги 5 и 6.
  • Акт приёма-передачи (выдача заказчику) — две подписи: председатель (открыл выдачу), затем заказчик (получил). Шаги 7 и 8.
  • Товарно-транспортная накладная — при доставке через экспедитора, подписи вне блокчейна (поставщик, председатель, экспедитор).

4. Движение по кошелькам

  • Паевой взнос → резерв под заказ: при создании заказа средства заказчика блокируются под конкретный заказ (недоступны до конца цикла).
  • Резерв → членский кошелёк Стола заказов: при отмене заказа или недовыдаче средства возвращаются и остаются в программе на следующие заказы.
  • Паевой взнос → членский кошелёк Стола заказов: при доплате за большее количество (добирает резерв; напрямую с паевого не списывается).
  • Резерв списывается: при выдаче имущества зарезервированная сумма уходит как целевой членский взнос.
  • Оплата поставщику идёт с расчётного счёта кооператива (бухгалтерский счёт, не кошелёк) после фактического банковского перевода.

⚠️ На ревью (НЕ правил):

  • CRITICAL drift (autofixable=false, НЕ применял): action marketplace::expirecycle — в коде реальное имя expireorder (src/p.mkt.supply/expireorder.cpp). Требует решения: переименовать в стандарте или подтвердить расхождение.
  • CRITICAL drift: action marketplace::acceptbatch — в коде acceptorder (active→accepted, без ledger2).
  • CRITICAL drift: action marketplace::declinebatch — в коде declineorder (active→cancelled, o.mkt.unlock).
  • CRITICAL drift: action marketplace::prepship и привязанный документ ТТН (registry_id 0) — в коде отсутствуют; комментарий в table_marketplace_orders.hpp фиксирует, что шага «готов отгрузить» нет, accepted→supply_prepared идёт сразу через signsupp. Возможно весь шаг prepship и состояние ship_ready выдуманы.
  • CRITICAL drift: state ship_ready отсутствует в namespace OrderStatus (реальные: active/cancelled/accepted/supplyprep/acceptcoop/readyrecv/received). Висит между accepted и supply_prepared.
  • WARNING: documents registry_id 702/802 кодом не закрепляются — в .cpp нет Document::validate_registry_id, только verify_document_or_fail; значения ведутся по note методолога. Реестровые папки 702.AssetContributionAct/802.ReturnByAssetAct существуют, но привязки в коде нет.
  • INFO (сужение графа, не правил): payout/payconfirm/paydecline в коде возможны не только в accepted_to_coop, но и в ready_to_receive/received (status==ACCEPTED_TO_COOP||READY_TO_RECEIVE||RECEIVED). Стандарт описывает триплет только на accepted_to_coop.
  • INFO: описание o.mkt.purch ранее говорило «срабатывает атомарно с o.mkt.payout» — в коде o.mkt.payout применяется отдельно в callback payconfirm (lazy, L12). Текст исправлен на lazy-модель; смысловой дрейф отмечаю для подтверждения.
  • SOFT (не правил, для ревью): проводки Дт/Кт и фразы «оба кошелька на счёте 86», «упрощённая модель без счёта 60» оставлены в descriptions — понятны бухгалтеру, но при желании можно вынести в отдельную бух-секцию.
  • SOFT: backend как бизнес-роль («Автоматизированная служба кооператива») — проверить, устраивает ли формулировка методолога, или роль трактуется как чисто техническая.

p.mkt.wroff.standard.yaml — Утилизация скоропорта

Утилизация скоропорта

Периодическое списание со склада участка имущества, которое физически пропало или стало непригодным к выдаче заказчику (просрочка, повреждения, малоценка).

1. Последовательность действий

  1. Председатель — по расписанию (по умолчанию раз в месяц, дату согласует бухгалтер) опрашивает склады участков, собирает позиции к списанию, подписывает заявление и вносит проект на рассмотрение совета.
  2. Совет — рассматривает заявление по типовому процессу решения совета; при положительном решении председатель подписывает протокол, при отрицательном — проект отклоняется.
  3. Председатель (от имени кооператива) — по принятому протоколу списывает каждую позицию проекта со склада. Когда списаны все позиции — проект завершён.

2. Проводки

Когда Дт Кт Смысл
Шаг 3, по каждой позиции 86 (Целевое финансирование) 10 (Материалы) Стоимость выбывающего имущества относится на расход целевых средств программы; имущество уходит из учёта как безвозвратные потери.

3. Документы

  • Заявление о списании скоропорта — подписывает председатель на шаге 1 перед внесением проекта на совет (список: участок, наименование, количество, сумма, причина).
  • Протокол совета о списании скоропорта — подписывает председатель на шаге 2 после положительного решения совета (документ типового процесса решения совета).

4. Движение по кошелькам

Нет. Это чисто бухгалтерское событие: имущество выбывает со склада и относится на расход целевых средств программы. Кошельки заказчиков и кооператива не двигаются, ничего не блокируется. Имущество учитывается отдельно по каждому участку.

⚠️ На ревью (НЕ правил):

  • actions[0].amount_ref / поле суммы: проверено и исправлено по коду; но дрейф имени поля (cost→amount) стоит подтвердить ревьюером, что struct wroff_item в table_marketplace_writeoff_proposals.hpp действительно field amount (findings autofixable=true, применено механически).
  • guard/actor: в transitions actor переходов ∅→proposed и authorized→executed указан chairman, а propwroff.cpp/execwroff.cpp используют require_auth(coopname) + Branch::is_user_authorized(signer). Расхождение терминологическое (бизнес-роль vs техническая авторизация) — оставлено как есть, нужно решение ревьюера (autofixable=false).
  • documents: контракт p.mkt.wroff не вызывает Document::validate_registry_id для 1106/1105 в самих экшнах — валидация делегирована типовому процессу решения совета. По дизайну, но отметить на ревью (autofixable=false).
  • SOFT-замечания языка (не применял, на ревью PR): header «Модель кошельков» с жаргоном «per-КУ субсчета» (строки 17-20); служебный блок «Источники правды в коде» с техно-именами OPERATION_REGISTRY/processes::marketplace::WRITEOFF/o.mkt.wroff (строки 27-34); комментарий «Имена actions ≤12 символов eosio::name» (строки 69-73); комментарий states с «таблица wroffprops, scope=coopname» (строки 99-104); documents[].note с путями-источниками components/cooptypes/.../1106 и 1105; operations[0].description с дублированием проводки и калькой «несколько последовательных операций в одной транзакции»; inline-метки L1/L2/L3 в операции.

Контракт soviet — стандартов 3

sov.authpkg.standard.yaml — Автоматизированное принятие решений советом

Автоматизированное принятие решений советом

Общий механизм: любой процесс (приём пайщика, заём, расход, инвестиция, общее собрание, маркетплейс), которому нужно согласие совета, передаёт совету пакет документов; совет голосует; согласие (или отказ) автоматически возвращается в исходный процесс.

1. Последовательность действий

  1. Исходный процесс → совет. Процесс передаёт пакет документов и заранее указывает, что произойдёт при согласии и при отказе совета. Повестка поступает в совет, начинается голосование.
  2. Члены совета → голосование. Голосуют «за»/«против», могут отозвать голос до окончания. При большинстве «за» решение считается одобренным.
  3. Председатель → подписывает протокол. Решение становится готовым к исполнению.
  4. Любой пайщик → исполнение. Согласие совета применяется к исходному процессу, и он продолжается дальше.

Ветки: большинство «против» — исходный процесс получает отказ; не уложились в срок — решение отменяется как просроченное, согласия нет.

2. Проводки

Нет. Сам процесс голосования не двигает средства по кошелькам и не создаёт бухгалтерских проводок (Дт/Кт). Все движения средств возникают уже внутри исходных процессов после получения согласия совета — и описаны в их собственных стандартах.

3. Документы

  • Протокол решения совета — подписывает председатель на шаге 3 (подписание протокола). Хранится при записи решения.
  • Документ повестки приходит из исходного процесса — у каждого свой (заявление о приёме, заявление на заём и т. д.); здесь не фиксируется. В отдельных процессах вместо общего протокола может применяться особый шаблон (например, «Решение совета о приёме пайщика») — это задаёт родительский стандарт.

4. Движение по кошелькам

Нет. На этом процессе средства по кошелькам не двигаются и ничего не блокируется — он только фиксирует согласие/отказ совета. Любые движения средств происходят в исходных процессах после получения согласия.

⚠️ На ревью (НЕ правил):

  • [critical, autofixable=false] transitions[] pending→rejected по soviet::voteagainst: в коде voteagainst.cpp перехода нет — add_vote_against лишь делает votes_against.push_back(username), не считает консенсус и не переводит решение в отказ. Фактический путь отказа — cancelexprd (истёк срок, erase) либо decline_callback внутри effect на exec. Транзишен описывает несуществующую в коде смену статуса. Гард «Большинство голосов против» в коде отсутствует. Требует решения ревьюера: убрать переход / переразметить как virtual через просрочку, или это намеренная модель.
  • [warning, autofixable=false] documents[0] registry_id=600: authorize.cpp проверяет document только через verify_document_or_fail(document), БЕЗ Document::validate_registry_id(document, 600) — код не пинит реестр 600, принимает документ любого реестра. Стандарт декларирует жёсткое закрепление id, код не валидирует. Оставлено как есть (структурное поле); решение — ослабить формулировку привязки или закрепить валидацию в коде.
  • [info, autofixable=false] states[] (pending/approved/authorized/executed/rejected) не сверяемы 1:1 с кодом: у soviet::decision нет namespace Status; статусы синтетические (флаги validated/approved/authorized + erase записи). Это моделирование, не зеркало enum. Расхождением кода не является, отмечено для ревью.
  • [info, autofixable=false] exec не вызывает обобщённый confirm/decline callback по полям, а делает hardcode-диспетч if/else по decision->type (withdraw_effect/subaccum_effect/freedecision_effect/authorize_action_effect); erase записи — внутри effect, не в exec. По смыслу совпадает со стандартом, отмечено для точности.

sov.decision.standard.yaml — Принятие свободного решения советом

Принятие свободного решения советом

Путь, по которому совет голосует по произвольному вопросу повестки: инициатор сам формирует и подаёт повестку, совет голосует, председатель подписывает протокол. Для решений, не привязанных к стандартизованному процессу.

1. Последовательность действий

  1. Инициатор (член совета или пайщик) → подаёт документ повестки. Вопрос ставится на голосование, членов совета оповещают.
  2. Члены совета → голосуют «за» / «против» (голос можно отозвать*). При большинстве «за» решение считается одобренным.
  3. Председатель → подписывает протокол решения. Решение готово к исполнению.
  4. Любой пайщик / системный триггер → исполняет решение: факт принятия фиксируется, запись о голосовании закрывается.

Примечание для ревью: в коде отзыв голоса сейчас фактически заблокирован — см. unresolved (дрейф cancelvote).

Ветки: при большинстве «против» — решение отклонено, протокол не оформляется. При просрочке — любой член совета может отменить решение как просроченное (закрывается без исполнения).

2. Проводки

Нет. Свободное решение само по себе не двигает средства и не делает бухгалтерских проводок — это путь принятия решения. Конкретные финансовые последствия (если совет так решил) оформляются отдельным процессом вне рамок этого стандарта.

3. Документы

Шаг Документ Подписывает
1. Подача повестки Предложение повестки дня собрания совета Инициатор
3. Утверждение Протокол решения совета Председатель

Второй документ (протокол) подписывается председателем на шаге утверждения и прикладывается к решению.

4. Движение по кошелькам

Нет. Процесс не блокирует и не перемещает средства ни по каким кошелькам. Внешний эффект свободного решения — фиксация самого факта решения; любое конкретное действие выполняется вне этого процесса (свободная воля совета).

⚠️ На ревью (НЕ правил):

  • ДРЕЙФ (autofixable=false, на ревью): actions[soviet::cancelvote] — в коде src/vote/cancelvote.cpp вторая строка тела eosio::check(false, «Отмена голоса запрещена»), отзыв голоса жёстко запрещён и недостижим. Стандарт же описывает cancelvote как рабочее действие и упоминает его в сценарии («голос можно отозвать»). Поведенческий дрейф: либо вернуть отзыв голоса в коде, либо убрать действие из стандарта. Не правил автоматически — нужно решение по сути.
  • INFO (autofixable=false): у сущности decision нет namespace Decision::Status с enum-константами; статусы (created/approved/authorized/executed/rejected) выводятся из bool approved/authorized и факта наличия/удаления строки. Моделирование в стандарте корректно (rejected помечен kind: virtual), но 1:1 state→константа в коде отсутствует.
  • INFO (autofixable=false): привязка документов к экшнам не подкреплена validate_registry_id в .cpp — freedecision.cpp не валидирует registry_id 599, authorize.cpp зовёт generic verify_document_or_fail без проверки id 600. Покрытие формально 1:1, но проверки конкретного registry_id на уровне контракта нет.
  • SOFT (на ревью, не правил): шапка-комментарий с путями к исходникам (строки 8-15) — адресована разработчику, а не бизнес-читателю; кандидат на удаление из стандарта.
  • SOFT: header (строка 6) «формируются контрактом-инициатором — см. sov.authpkg» — техническая ссылка; предложено заменить на «…автоматически в рамках другого, стандартизованного процесса».
  • SOFT: votefor.purpose «статус решения переводится в approved» и voteagainst.purpose «переходит в статус rejected» — мягко рекомендовано «считается одобренным/отклонённым».
  • SOFT: alternatives[Отклонение голосованием].description «помечается как rejected» — мягкая правка на «считается отклонённым».
  • SOFT: documents[].stored_in (decisions.statement / decisions.authorization) — техническая деталь хранения; рассмотреть удаление как служебного поля.

sov.selectbranch.standard.yaml — Прикрепление пайщика к кооперативному участку

Прикрепление пайщика к кооперативному участку

Простой одношаговый процесс. Пайщик выбирает кооперативный участок (территориальную единицу кооператива), к которому будет относиться. Заявление принимается сразу, без отдельного решения совета.

1. Последовательность действий

  1. Пайщик оформляет и подписывает (ЭЦП) заявление о выборе кооперативного участка.
  2. Кооператив проверяет: пайщик состоит в кооперативе и выбранный участок существует.
  3. Кооператив закрепляет пайщика за выбранным участком и сразу фиксирует заявление в реестре документов.

Итог: пайщик прикреплён к участку (конечное состояние).

2. Проводки

Нет. Процесс нефинансовый — движения средств и бухгалтерских проводок не порождает.

3. Документы

  • Заявление пайщика о выборе кооперативного участка — подписывает пайщик на шаге 1. Фиксируется в реестре документов кооператива.

4. Движение по кошелькам

Нет. Кошельки не затрагиваются, ничего не блокируется и не переводится.

⚠️ На ревью (НЕ правил):

  • header-комментарий (строки 3-9) содержит «action», «реализован в контракте Soviet», имя реестра «participants» и путь к .cpp в прозе — soft-замечание, не автофикшу; на PR-ревью переформулировать в бизнес-пояснение, путь оставить только в structured entity_source.
  • Дрейф (state, warning, autofixable=false): у сущности participant нет namespace Status; реальные значения status в коде — свободные литералы accepted/blocked, значения «attached» нет. selectbranch меняет braname, а не status — состояние «attached» в стандарте описывает факт заполнения braname, не статус сущности. Требует решения методолога: оставить как «логическое состояние» или переописать.
  • Дрейф (document, info, autofixable=false): registry_id=101 в коде не enforced — selectbranch.cpp вызывает verify_document_or_fail(document) (только подписи), validate_registry_id(…, 101) не вызывается. Привязка 101 — договорённость стандарта, а не проверка контракта; пометить на ревью.

Контракт registrator — стандартов 2

p.reg.accept.standard.yaml — Приём пайщика

Приём пайщика

Корневой процесс вступления человека или организации в кооператив.

1. Последовательность действий

  1. Кандидат подаёт заявление о вступлении, выбирает кооперативный участок и подписывает ЭЦП → кооператив открывает заявку и выставляет счёт на оплату регистрационного взноса (вступительный + минимальный паевой). Совет получает оповещение.
  2. Кассир сверяет поступление денег с выставленным счётом и подтверждает оплату → заявка идёт на рассмотрение совета. Взносы пока на учёт не поставлены.
  3. Совет принимает положительное решение → кандидат становится активным пайщиком, включается в список членов, и оба взноса одновременно встают на учёт.

Ветки отказа: кассир может отклонить оплату (если деньги не пришли/отозваны), совет может отказать в приёме — в обоих случаях заявка закрывается, взносы на учёт не ставятся, возврат уже уплаченных денег оформляется отдельной процедурой.

2. Проводки (на шаге 3, при одобрении совета)

  • Дт 51 / Кт 86 — вступительный взнос пайщика (целевое поступление в кооперативный фонд).
  • Дт 51 / Кт 80 — минимальный паевой взнос при регистрации (в паевой фонд кооператива).

Обе проводки делаются одновременно в момент решения совета о приёме, не раньше.

3. Документы и подписи

  • Заявление на вступление в кооператив — подписывает кандидат на шаге 1.
  • Решение совета о приёме пайщика — подписывает совет на шаге 3 (закрывающий шаг).

4. Движение по кошелькам

  • На шаге одобрения советом средства встают на учёт: вступительный взнос — на кошелёк вступительных взносов; минимальный паевой — на кошелёк минимальных паевых взносов.
  • До решения совета (шаги 1–2) деньги числятся как оплаченные, но ни на один кошелёк ещё не зачислены.
  • При отказе (кассира или совета) на кошельки ничего не зачисляется.

⚠️ На ревью (НЕ правил):

  • [document, autofixable=false] registry_id=100 (reguser/statement) и registry_id=501 (confirmreg/authorization) в YAML не закреплены кодом: reguser.cpp:55 делает только verify_document_or_fail(statement) без validate_registry_id, confirmreg.cpp не валидирует параметр authorization вовсе. ID правдоподобны и подкреплены реестром, но не подтверждены кодом — оставлено как есть, нужно ревью/решение по привязке.
  • [soft] Шапка: слова «Манифест», «tagline» — заменить на человеческое «к каждому разделу короткая суть одной строкой и развёрнутое пояснение».
  • [soft] process_type как термин встречался в прозаических комментариях — соответствующие комментарии уже переписаны; само поле process_type: p.reg.accept оставлено (структурный идентификатор).
  • [soft] entity: «registrator::candidate → registrator::account» — структурное поле; рядом есть человеческое entity_human «Кандидат → пайщик», при желании очистить.
  • [soft] documents[].stored_in (строка про authorization): «(authorization — в параметре действия, не хранится в candidates после удаления записи)» — прозаическое пояснение с техническими словами; заменить на бизнес-смысл или оставить пустым.
  • [soft] «выставляет счёт» в purpose/scenario — легитимная идиома «счёт на оплату»; при желании уточнить «счёт на оплату регистрационного взноса», чтобы не путать со счетами 80/86.

reg.coop.standard.yaml — Присоединение к платформе кооперативной экономики

Присоединение к платформе кооперативной экономики

Кооператив подключается к цифровой платформе «Кооперативная Экономика»: председатель подписывает соглашение о присоединении, после чего часть паевого взноса конвертируется в членский взнос платформы (AXON) — оплату её ресурсов (документооборот, операции, хранение).

1. Последовательность действий

  1. Председатель подписывает соглашение о присоединении и направляет его регистратору. Кооператив регистрируется на платформе в статусе «Соглашение подписано» и ожидает авторизации совета.
  2. Совет провайдера выполняет конвертацию: часть паевого взноса переводится в членский взнос платформы (AXON) по курсу 10:1. Кооператив становится активным членом платформы.

Замечание ревью: по факту кода статус «активен» выставляет отдельное действие регистратора (stcoopstatus), а не конвертация — см. unresolved.

2. Проводки

Когда Дт Кт Смысл
Конвертация паевого взноса в членский 80 (Паевой фонд) 86 (Целевое финансирование) Часть паевого капитала кооператива превращается в целевые поступления платформы

3. Документы

Шаг Документ Кто подписывает
1 Соглашение (оферта) о присоединении к платформе Председатель
2 Заявление о конвертации паевого взноса в членский взнос Председатель

Оба документа сохраняются в реестре документов платформы.

4. Движение по кошелькам

  • При конвертации: средства списываются из паевого фонда кооператива и зачисляются в фонд членских (делегатских) взносов платформы.
  • После перевода кооперативу начисляется членский взнос платформы (AXON).
  • Условие: в паевом фонде кооператива достаточно средств для конвертации.

⚠️ На ревью (НЕ правил):

  • [critical, autofixable=false] transitions[1] (pending→active, soviet::converttoaxn): по коду converttoaxn НЕ меняет cooperatives2.status — статус active реально выставляет registrator::stcoopstatus(status=active). Граф состояний приписывает переход не тому действию. Требует решения: либо добавить действие stcoopstatus в стандарт, либо переосмыслить связку. Не правил — возможный баг/семантика.
  • [warning, autofixable=false] documents[0] (registry_id=50): regcoop.cpp сохраняет document без validate_registry_id/verify_document_or_fail — кодовой привязки к реестру 50 нет (в отличие от converttoaxn.cpp, который явно проверяет registry_id=51). registry_id=50 в structured-поле документа может не отражать код. На ревью PR.
  • [info, autofixable=false] states: в коде существует статус blocked (stcoopstatus.cpp: active|blocked|pending), не отражённый в стандарте. Для фокусного стандарта присоединения не обязателен — отметка для ревью.
  • [soft] actions[converttoaxn].purpose и operations[o.sov.axncnv].description: проводка «Дт 80 / Кт 86» в прозе дублирует раздел операций (L1). Можно опустить — оставлено на усмотрение ревьюера.
  • [soft] scenario.steps[2].pre[0]: «Кооператив в статусе pending» — сырой статус; можно заменить на человеческое «Соглашение подписано». Оставлено.

Контракт wallet — стандартов 2

p.wal.depo.standard.yaml — Внесение паевого взноса

Внесение паевого взноса

Пайщик пополняет свой паевой кошелёк деньгами. Документ не оформляется — взнос подтверждается самим фактом платежа через кассира.

1. Последовательность действий

  1. Пайщик инициирует внесение взноса с указанием суммы → создаётся заявка «ожидает оплаты», пайщику выставляется платёжный счёт.
  2. Пайщик оплачивает счёт; деньги поступают на расчётный счёт кооператива.
  3. Кассир подтверждает поступление платежа → сумма зачисляется на паевой кошелёк пайщика, заявка закрывается («Взнос учтён»).
    • Альтернатива: платёж не прошёл / отменён → кассир отклоняет оплату, заявка закрывается, взнос не зачисляется. Пайщик может подать заявку заново.

2. Проводки

Когда Дебет Кредит Смысл
При подтверждении оплаты кассиром Дт 51 (расчётный счёт) Кт 80 (паевой фонд / складочный капитал) Деньги пайщика поступили на расчётный счёт и увеличили складочный капитал кооператива

3. Документы

Не подписываются. Взнос не требует договора — основание — сам факт платежа.

4. Движение по кошелькам

  • Зачисление взноса: на паевой кошелёк пайщика поступает сумма взноса (первичный вход средств). Списаний и блокировок нет.
  • Средства становятся доступны пайщику для дальнейших кооперативных процессов — займов, инвестиций, поставок, выходов.
  • Напоминание: «платёжный счёт» и «расчётный счёт 51» — это счета (документ-инвойс и бухгалтерский), а не кошелёк; зачисление взноса идёт именно на паевой кошелёк.

⚠️ На ревью (НЕ правил):

  • Findings сверки с кодом пусты — дрейфа structured↔код не обнаружено.
  • SOFT (стр. 11-15): блок «Источники правды в коде» в шапке содержит ledger2/operations.hpp и o.wal.depcpl как технический указатель для разработчика. Аудит классифицировал как допустимый; на ревью решить — оставить пути к файлам без дублирования имён операций или удалить блок целиком.
  • SOFT (states[1], стр. 75): номера счетов «(счета 51 / 80)» в описании состояния дублируют проводку §6 — можно опустить или оставить как пояснение бухгалтеру.
  • SOFT (guards[0] перехода ∅→pending, стр. 90): «Пайщик имеет статус active» — техно-значение «active»; можно заменить на «действующий участник», но это guard-поле (semi-structured), оставил без правки для ревью.
  • SOFT (operations[0].description, стр. 174-175): проводка Дт 51/Кт 80 в прозе дублирует L1-поля debit/credit; текст корректен (51 расчётный, 80 паевой фонд), можно оставить как пояснение бухгалтеру.

p.wal.wthdrw.standard.yaml — Возврат паевого взноса

Возврат паевого взноса

Пайщик получает обратно ранее внесённый паевой взнос деньгами. Обратный процесс к внесению взноса.

1. Последовательность действий

  1. Пайщик подаёт и подписывает заявление на возврат → заявка регистрируется, сумма резервируется, вопрос выносится в совет.
  2. Совет авторизует выплату единым решением → в платёжную систему уходит поручение на выплату пайщику.
  3. Кассир (оператор платёжной системы) подтверждает выплату → деньги ушли пайщику банковским переводом, заявка закрывается.
  • Альтернатива: отказ совета или платёжной системы на любом шаге до выплаты → зарезервированная сумма возвращается пайщику, заявка закрывается.

2. Проводки

  • Резервирование (шаг 1) и возврат при отказе — без проводки (движение по кошелькам, бухгалтерский счёт не меняется).
  • Подтверждение выплаты (шаг 3): Дт 80 «Паевой фонд» / Кт 51 «Расчётный счёт» — паевой фонд уменьшился, деньги ушли с расчётного счёта пайщику.

3. Документы

  • Шаг 1: «Заявление на возврат паевого взноса денежными средствами» — подписывает пайщик.
  • Шаг 2: «Решение совета о возврате паевого взноса (авторизация на выплату)» — подписывает совет.

4. Движение по кошелькам

  • Шаг 1: сумма возврата переводится с паевого кошелька пайщика → в кошелёк-резерв выплат (резервируется).
  • Шаг 3 (выплата): сумма списывается из кошелька-резерва выплат → уходит пайщику банковским переводом (получателя на цепи нет).
  • Отказ: зарезервированная сумма возвращается из кошелька-резерва выплат → обратно на паевой кошелёк пайщика.

(Кошелёк ≠ бухгалтерский счёт: счета 80/51 — только в проводке шага 3; движение между кошельками проводок не создаёт.)

⚠️ На ревью (НЕ правил):

  • soft: header comment (строки 12-18) — блок технических ссылок на код (o.wal.wthcpl, ledger2, processes::wallet::WITHDRAW) избыточен для нетехнаря; уместен как служебная сноска, но можно вынести/сократить — на усмотрение ревью
  • soft: operations[0].human_name (o.wal.wthreq) «Резервирование паевого под запрос на возврат» — допустимо; яснее «Резервирование суммы возврата на кошельке-резерве выплат»
  • soft: operations[2] inline-комментарий «# кошелёк-резерв возвратов» (строка 266) — можно унифицировать с прозой на «кошелёк-резерв выплат»
  • soft: transitions[0].guards «withdraw_hash уникален» — можно очеловечить до «Заявка на возврат не дублирует уже существующую»
  • soft: проводки Дт 80 / Кт 51 в action[2].purpose и state completed описаны как дублирующие L1 — рассмотреть удаление из прозы (оставлены, т.к. бухгалтеру допустимы)
  • info/autofixable=false (НЕ применено, баг/семантика кода — для ревью): (1) registry_id 900/901 — в .cpp нет validate_registry_id, привязка id→документ on-chain не проверяется (только хранением); (2) устаревшие комментарии в createwthd.cpp/declinewthd.cpp пишут BLOCK/UNBLOCK на w.wal.share, тогда как реальные операции — TRANSFER (стандарт описывает корректную TRANSFER-механику); (3) у withdraw нет Status-namespace, status — свободный eosio::name; completed/removed в коде не хранятся (erase) — в стандарте корректно помечены final/virtual

Контракт meet — стандартов 1

meet.hold.standard.yaml — Проведение общего собрания пайщиков

Проведение общего собрания пайщиков

Высший орган управления кооперативом в действии: от подачи повестки и авторизации советом до сбора бюллетеней и подписи протокола. При недостижении кворума собрание перезапускается с понижением требования к кворуму.

1. Последовательность действий

  1. Пайщик-инициатор → формирует повестку (до 10 вопросов), назначает председателя и секретаря, задаёт окно голосования (открытие не ранее чем через 15 дней), подписывает предложение повестки. Статус → «Повестка подана».
  2. Совет → принимает решение о созыве (типовой автоматизированный процесс совета) и подписывает авторизацию. Статус → «Совет авторизовал».
  3. Пайщики → подписывают уведомления о собрании (фиксируются в списке оповещённых). Идёт параллельно с голосованием.
  4. Пайщики → в окне голосования подписывают бюллетени по всем вопросам (за/против/воздержался); пересчитывается достигнутый процент кворума.
  5. Секретарь → после закрытия окна и при достигнутом кворуме подписывает протокол. Статус → «Подписано секретарём».
  6. Председатель → подписывает протокол; итог по каждому вопросу подводится по правилу большинства (50% + 1 голос). Статус → «Собрание состоялось», решения приняты.
  • Альтернатива (перезапуск): если кворум не собран, инициатор подаёт новую повестку с новыми датами — цикл растёт, требование к кворуму понижается, процесс возвращается на шаг авторизации советом.

2. Проводки

Нет. Общее собрание не двигает кошельки и не делает бухгалтерских проводок — принятые решения исполняются вне этого процесса.

3. Документы

Шаг Документ Подписывает
1. Создание повестки Предложение повестки дня общего собрания Пайщик-инициатор
2. Авторизация Решение совета о созыве общего собрания Совет
3. Оповещение Уведомление о проведении общего собрания Пайщик
4. Голосование Заявление с бюллетенем для голосования Пайщик
5. Подпись секретаря Протокол решения (подпись секретаря) Секретарь
6. Подпись председателя Протокол решения (подпись председателя) Секретарь + Председатель
Перезапуск Предложение повестки (повторное) Пайщик-инициатор

Протокол секретарь подписывает первым, председатель накладывает свою подпись на тот же протокол вторым — собрание становится состоявшимся только после обеих подписей.

4. Движение по кошелькам

Нет. Средства по кошелькам в рамках этого процесса не движутся и ничего не блокируется.

⚠️ На ревью (НЕ правил):

  • Граф: статус onrestart не имеет явного исходящего перехода в transitions[] (возврат к authorized идёт через authmeet, чей guard принимает status==onrestart||created); связность по факту есть, в YAML переход onrestart→authorized неявный, virtual:true смягчает. autofixable=false — на ревью.
  • Документы: привязка через verify_document_or_fail(...), а не Document::validate_registry_id(,); жёсткой проверки registry_id в сигнатуре нет, но покрытие 300-304 1:1 подтверждено папками реестра. autofixable=false — отмечен способ привязки.
  • soft: header comment (строки 8-16) — блок «Источники в коде» с путями .cpp читателю не нужен; пользователь предложил убрать, но это soft — оставил для ревью на PR.
  • soft: статус-имена created/onrestart/authorized/preclosed/closed в прозе actions[0..6].purpose, states[0].description, transitions[1].guards, scenario step1.post[0]/step1.pre/alternatives — предложены человеческие названия, но soft.
  • soft: actions[3].purpose (vote) и scenario step4.description — «контракт обновляет счётчики» предложено смягчить до «голоса учитываются».
  • soft: transitions[3].guards[2] и scenario step4.description — [open_at..close_at] предложено заменить на «окно голосования».
  • soft: transitions[0].guards (createmeet) — initiator/presider/secretary + coopname технические идентификаторы участников; аудит их не флагнул как hard, но это технический хвост — на усмотрение ревью.
  • soft: documents[2]/[3].stored_in: «documents-registry (по hash собрания)» — место хранения; если показывается читателю, заменить на «реестр документов собрания», иначе оставить как идентификатор.

# Контроль кооперативных стандартов (workflow `coop-standards-check`, агенты на Opus) Сквозной аудит всех 15 `.standard.yaml`: сверка с кодом + человеческий бизнес-язык прозы. Правки консервативные — техно-хвосты убраны из прозы (идентификаторы кошельков/операций, Gateway, ledger2, enum-имена счетов/кошельков), путаница **счёт ≠ кошелёк** устранена; structured-поля (Дт/Кт, кошельки, ledger_code, имена экшнов) не тронуты. Спорный дрейф с кодом (возможные баги, семантика статусов) НЕ правил — вынесено в блоки «⚠️ На ревью». Контрактов: 6, стандартов: 15. --- ## Контракт capital — стандартов 4 ### `p.cap.debt.standard.yaml` — Выдача займа пайщику ## Выдача займа пайщику Кооператив выдаёт пайщику беспроцентный целевой заём из паевого фонда на срок проекта. Возврат — автоматически при сдаче акта приёма-передачи проекта (отдельная заявка на возврат не нужна). ### 1. Последовательность действий 1. **Пайщик** подаёт заявление на заём → заявка зарегистрирована, под неё резервируется часть доступного пайщику лимита. 2. **Председатель** добавляет документ-одобрение → «Председатель одобрил». 3. **Совет** авторизует выплату → «Совет авторизовал»: заём считается выданным, кассир получает поручение на выплату. 4. **Кассир** подтверждает зачисление займа на банковский счёт пайщика → «Заём выплачен» (финал). Отказ: председатель/совет отклоняет на шагах 2–3 (лимит возвращается, движений денег нет); платёжная система не провела выплату на шаге 4 (заявка аннулируется). ### 2. Проводки | Когда | Дт | Кт | Смысл | |---|---|---|---| | Выплата займа (кассир подтвердил, шаг 4) | 58 «Финансовые вложения» | 51 «Расчётный счёт» | деньги ушли пайщику, у кооператива учтены как финансовое вложение | | Возврат по акту-2 (RID-flow*) | 80 «Паевой фонд» | 58 «Финансовые вложения» | вложение закрывается, сумма зачитывается в паевой фонд пайщика | \* Возврат (o.cap.repay) фактически относится к процессу РИД (акт-2), а не к процессу долга — см. unresolved. ### 3. Документы | Шаг | Документ | Подписывает | |---|---|---| | 1 | Заявление на получение займа | пайщик | | 2 | Решение о предоставлении займа (одобрение) | председатель | | 3 | Решение о предоставлении займа (авторизация) | совет | ### 4. Движение по кошелькам - **Выдача (шаг 4):** заём фиксируется на кошельке «Выданные пайщикам беспроцентные займы» — обязательство пайщика перед кооперативом. - **Резерв (шаг 1):** под заявку блокируется часть доступного пайщику лимита; при отказе — освобождается. - **Возврат (акт-2):** сумма переводится с кошелька выданных займов на паевой кошелёк пайщика (доступный остаток паевых взносов). > Счёт ≠ кошелёк: «расчётный счёт 51» и «банковский счёт пайщика» — бухгалтерские/банковские счета; кошельки — учётный слой движения средств кооператива. **⚠️ На ревью (НЕ правил):** - КРИТИЧНО (autofixable=false, семантика): операция o.cap.repay (triggered_by capital::debtpaycnfrm) по реестру кода принадлежит process_type p.cap.rid, а не p.cap.debt — REPAY проводится в RID-flow (signact2/акт-2), а debtpaycnfrm.cpp вызывает только LEND. Возможно, операцию o.cap.repay следует целиком убрать из стандарта долга. Не трогал — требует решения ревьюера/проверки кода, не механический фикс. - INFO (не расхождение): documents registry_id 1050/1051 — папки реестра существуют, но в .cpp процесса долга нет Document::validate_registry_id(1050/1051); привязка id↔код не enforced контрактом (createdebt использует verify_document_or_fail без проверки registry_id). Информативно. - SOFT (стиль, не применял): в operations[o.cap.lend]/[o.cap.repay].description проводки Дт58/Кт51 и Дт80/Кт58 в прозе дублируют L1-бухслой — можно опустить, оставив бизнес-смысл. Оставлено как есть (бухгалтер их понимает, §6 допускает Дт/Кт). - SOFT (стиль, не применял): inline-комментарий wallet_to:w.wal.share «ЦПП Цифровой Кошелёк — паевые взносы деньгами» можно сократить до «паевой кошелёк пайщика». --- ### `p.cap.invest.standard.yaml` — Приём инвестиции в программу ## Приём инвестиции в программу («Благорост») Пайщик переводит часть своих свободных паевых средств в инвестицию в программу «Благорост». Деньги физически остаются на расчётном счёте кооператива — меняется только то, как они учитываются у пайщика. Процесс одношаговый. ### 1. Последовательность действий 1. **Пайщик** → подписывает заявление об инвестировании в «Благорост» и подаёт его (действие `capital::createpinv`). 2. **Контракт** → проверяет: пайщик активен, средств достаточно, заявление не дубль и подписано; переводит указанную сумму в инвестицию и фиксирует факт в учёте. Итоговое состояние: **Инвестировано** (финальное). ### 2. Проводки **Бухгалтерских проводок нет.** Дебет/кредит не задаются (оба пустые). Средства не покидают паевой фонд и не меняют бухгалтерский счёт — это перенос внутри фонда. Для бухгалтера: счёт 80 (паевой фонд) не затрагивается, деньги остаются на расчётном счёте кооператива. ### 3. Документы - **Заявление об инвестировании денежных средств в «Благорост»** — подписывает **пайщик (Участник)** ЭЦП на шаге 1. ### 4. Движение по кошелькам - **Откуда:** свободные паевые средства пайщика. - **Куда:** инвестиция пайщика в программу «Благорост». - **Что блокируется:** инвестированная сумма перестаёт быть свободной — после перевода пайщик может участвовать в проектах программы как исполнитель. **⚠️ На ревью (НЕ правил):** - guard «уникальность invest_hash» (findings, autofixable=false): в createpinv.cpp нет явной проверки уникальности invest_hash; историческая таблица progrinvests @deprecated, createpinv в неё не пишет. Возможна неявная идемпотентность через operation_id в Ledger2::apply, но в самом экшне guard не реализован. Текст guard смягчён до «не повторяет ранее поданное», но фактическое наличие защиты надо подтвердить на ревью (или удалить guard, если защиты нет). - operations[0].human_name (soft): «Инвестиция в ЦПП «Благорост» (перенос между кошельками)» — рекомендация заменить уточнение в скобках на «(перенос внутри паевого фонда пайщика)» либо опустить как техническое. Не применял (soft). - scenario.steps[0].post[2] (soft): «Создана запись инвестиции в таблице» — рекомендация «Факт инвестиции зафиксирован в учёте пайщика». Не применял (soft). - post[0] и post[1] после правки звучат близко по смыслу (оба про зачисление суммы в инвестицию) — на ревью решить, не объединить ли их в один пункт. --- ### `p.cap.prop.standard.yaml` — Приём имущественного паевого взноса ## Приём имущественного паевого взноса Пайщик передаёт кооперативу имущество (не деньги, не РИД) как паевой взнос в программу «Благорост». ### 1. Последовательность действий 1. **Пайщик** подаёт предложение о внесении имущества (описание + сумма оценки) — предложение зарегистрировано. 2. **Председатель** одобряет предложение. 3. **Совет** авторизует приём имущества. 4. **Пайщик** ставит первую подпись на акте приёма-передачи (передаёт имущество). 5. **Председатель** ставит вторую подпись на акте — завершающее действие: имущество зачислено пайщику как паевой взнос. _Ветка отказа:_ председатель или совет отклоняет предложение (шаги 1–3) — запись удаляется, имущество как паевой взнос не зачисляется. ### 2. Проводки | Когда | Дт | Кт | Смысл | |---|---|---|---| | Вторая подпись председателя (шаг 5) | **4** — Нематериальные активы | **80** — Паевой фонд (складочный капитал) | Кооператив принял имущество (по сумме оценки), оно учтено как часть паевого фонда | Единственная проводка во всём процессе — на завершающей подписи. До неё движений по учёту нет. ### 3. Документы | Шаг | Документ | Подписывает | |---|---|---| | 1 | Заявление об инвестировании имущества в благорост | Пайщик | | 3 | Решение совета об инвестировании имущества | Совет | | 4 | Акт приёма-передачи (первая подпись) | Пайщик | | 5 | Акт приёма-передачи (вторая подпись) | Пайщик + Председатель | _На ревью:_ привязка документов к конкретным реестровым папкам в коде не проверяется; акт «первая/вторая подпись» в коде хранится в одном поле, а не в двух. ### 4. Движение по кошелькам - На завершающей подписи имущество (по сумме оценки) **зачисляется пайщику** в кошелёк программы «Благорост» как паевой взнос. Внешнего источника нет — это выпуск (зачисление) на сумму оценки. - До завершающей подписи и при отказе — никакого движения средств не происходит. **⚠️ На ревью (НЕ правил):** - [document, warning, autofixable=false] Ни один .cpp pgprp не вызывает Document::validate_registry_id — только verify_document_or_fail. Соответствие registry_id (1070→statement, 1071→authorization, 1072→act1/act2) в стандарте — допущение, не закреплённое и не верифицируемое контрактом. Решить на ревью: оставить как документную привязку или пометить как недоказанную. - [document, info, autofixable=false] Стандарт описывает два документа на registry_id 1072 (act1/act2) со stored_in pgproperties.act1 и pgproperties.act2, но в таблице program_property только одно поле act (document2); act1pgprp и act2pgprp пишут в одно поле. Полей act1/act2 в коде нет — расхождение модели документов. - [guard, soft] transitions[∅→created].guards[0] «Пайщик имеет статус active» → предложено «Пайщик состоит в кооперативе и активен» (не применял — soft). - [scenario, soft] scenario.steps[1].description содержит «property_hash» и technical-формулировку → предложено упростить (не применял — soft). - Замечание по коду (вне scope правки): комментарий в act2pgprp.cpp:47 ошибочно пишет «Dr 51», тогда как фактическая проводка из реестра = счёт 4. Стоит поправить комментарий в коде отдельно. --- ### `p.cap.rid.standard.yaml` — Приём результата интеллектуальной деятельности ## Приём результата интеллектуальной деятельности (p.cap.rid) Участник программы «Благорост» оформляет результат своей работы (РИД) как имущественный паевой взнос, а в конце распределяет полученный взнос между своим Цифровым Кошельком и программой. ### 1. Последовательность действий 1. **Участник** создаёт коммит РИД по проекту. 2. **Мастер проекта** одобряет коммит (либо отклоняет — тогда запись удаляется). 3. **Участник** после завершения проекта подаёт заявление о результате. 4. **Председатель** одобряет заявление. 5. **Совет** авторизует приём РИД (либо отклоняет на любой стадии — возврат к повторной подаче). 6. **Участник** ставит первую подпись на акте приёма-передачи. 7. **Председатель** ставит вторую подпись — РИД принят, при наличии займа он закрывается. 8. **Участник** распределяет паевой взнос между Цифровым Кошельком и программой «Благорост» — процесс завершён. ### 2. Проводки - **Шаг 2 (одобрение коммита):** Дт 8 (вложения во внеоборотные активы) / Кт 80 (паевой фонд) — РИД зачислен в паевой фонд участника. - **Шаг 7 (приём по акту):** Дт 4 (нематериальные активы) / Кт 8 — РИД принят в НМА на полную стоимость результата. - **Шаг 7 (опционально, заём):** Дт 80 (паевой фонд) / Кт 58 (финансовые вложения) — закрытие беспроцентного займа участника, сумма высвобождается на его паевом взносе. - **Шаг 8 (распределение):** новых проводок нет — бухгалтерская запись уже сделана при приёме РИД в НМА; это только перераспределение средств участника. ### 3. Документы - **Заявление о взносе РИД** — подписывает участник (шаг 3), затем председатель добавляет подпись при одобрении (шаг 4). - **Протокол решения совета** о приёме паевого взноса РИД — совет (шаг 5). - **Акт приёма-передачи РИД** — первая подпись участника (шаг 6), вторая подпись председателя (шаг 7). - **Заявление о распределении паевого взноса** — участник (шаг 8). ### 4. Движение средств участника - При одобрении коммита РИД зачисляется в **паевой фонд участника** (по программе «Благорост»). - При приёме по акту движения средств участника не происходит — приём идёт только в бухучёте; накопленный взнос остаётся неразделённым. - При наличии беспроцентного займа проекта он закрывается, высвобожденная сумма становится доступной на паевом взносе участника. - В финале участник распределяет паевой взнос: часть — в **Цифровой Кошелёк**, часть остаётся в программе **«Благорост»** (любая из частей может быть нулевой). **⚠️ На ревью (НЕ правил):** - [info, autofixable=false] Ни один .cpp процесса p.cap.rid не вызывает Document::validate_registry_id — привязка документа к registry_id не enforced on-chain (только verify_document_or_fail по подписи). Соответствие id берётся из комментариев/папок реестра. На ревью подтвердить, что 1040/1041/1042/1080 корректны методологически. - [info, autofixable=false] Имена состояний в стандарте — нарративные вехи (commit_created/approved/pushed/...), а не литеральные C++ Status-константы (Results::Status{CREATED,APPROVED,AUTHORIZED,ACT1,ACT2,DECLINED}; Segments::Status{...,CONTRIBUTED}). Расхождения нет, но при желании можно добавить маппинг нарратив→константа в комментарии. - [soft] Шапка «Источники правды в коде» (строки 15-19) — технические ссылки на .cpp/.hpp избыточны для читателя-бухгалтера; допустимо вынести в служебный блок или удалить, и убрать перечисление имён o.cap.* . Не применял (soft). - [soft] guards и inline debit-комментарии с registry_id=1040/1041/1042 и «Дт 4 / Кт 8 уже сделана в o.cap.accept» (строки 542, 556) — soft, оставлены: убрать ссылку на имя операции из debit-комментария («бухгалтерская запись сделана при приёме РИД в нематериальные активы») и упростить guards (registry_id, rfrshsegment, intellectual_cost) на ревью. - [soft] operations[o.cap.repay].description содержит номера счетов в прозе (Кт 58 / Дт 80) — финдинг предлагает убрать перечисление номеров из прозы (они уже в полях debit/credit). Не применял (soft). --- ## Контракт marketplace — стандартов 3 ### `p.mkt.return.standard.yaml` — Гарантийный возврат имущества ## Гарантийный возврат имущества Заказчик в пределах гарантийного срока возвращает имущество на склад участка и получает обратно сумму заказа. ### 1. Последовательность действий 1. **Заказчик** подаёт заявление на гарантийный возврат — указывает причину (некондиция, истёк срок годности, иное), прикладывает фото товара, ссылается на акт приёма-передачи. Только пока не истёк гарантийный срок поставщика. 2. **Председатель участка** рассматривает заявление удалённо (по фото и описанию) и решает: пригласить на очный визит или отказать удалённо. 3. Если визит одобрен — **заказчик** приходит на участок с продукцией, **председатель** очно осматривает товар и выносит финальное решение: принять возврат или отказать на месте. 4. При принятии возврата товар остаётся на складе участка, сумма заказа возвращается заказчику. При отказе (удалённо или очно) — процесс завершён, движений по имуществу и средствам нет. ### 2. Проводки (только при принятии возврата) - **Дт 10 «Материалы» / Кт 86 «Целевое финансирование»** — имущество возвращается на склад участка за счёт целевого финансирования (зеркало выдачи). ### 3. Документы - **Заявление пайщика на гарантийный возврат имущества** (с фото) — подписывает **заказчик** на шаге 1. - **Решение председателя о принятии возврата** — подписывает **председатель** на шаге 3 (специализированный шаблон в реестре пока не заведён — см. unresolved). - Отказы (удалённый / очный) фиксируются в системе как процедурное решение, отдельным документом в MVP не оформляются. ### 4. Движение по кошелькам - При принятии возврата заказчику восстанавливается сумма заказа на его **программном членском кошельке «Стола заказов»** (зеркально ранее списанной при выдаче). - Средства остаются в программе: заказчик направляет их на следующие заказы либо отдельным действием выводит в **универсальный членский кошелёк**. - Ничего не блокируется; при отказе движений по кошелькам нет. **⚠️ На ревью (НЕ правил):** - Дрейф documents[].accretrn registry_id=0 (autofixable=false): папки 0.* в реестре нет (placeholder), реальный документ «Решение председателя КУ» не существует; в коде accretrn привязки registry_id нет, decision верифицируется только по подписи. Нужен специализированный шаблон в registry либо in-system запись — решение методолога, не автофикс. - Дрейф documents[].submretrn registry_id=800 (autofixable=false): папка 800.ReturnByAssetStatement существует, но submretrn.cpp НЕ вызывает validate_registry_id(statement,800) и не verify_document_or_fail для statement — привязка декларирована только в YAML. Плюс по памяти проекта registry_id=800 = старый клиринговый контур, не членская модель. Требует решения: либо завести новый registry_id рядом с актами/ТТН, либо подтвердить привязку в коде. - soft operations[0].human_name «Гарантийный возврат — восстановление средств и имущества» — рядом ISSUE/debit/credit (structured), human_name человечный; помечен soft для единообразия, не трогал. - soft inline-комментарий строки 323-324 (маркер L1): «# L1 — двойная запись: имущество возвращается на склад через целевое финансирование» — по сути бизнесовый, но содержит маркер уровня L1; оставлен как soft на ревью. --- ### `p.mkt.supply.standard.yaml` — Прямая поставка-приобретение имущества ## Прямая поставка-приобретение имущества (Стол заказов) ### 1. Последовательность действий 1. **Заказчик** размещает заказ (товар, количество, пункт выдачи на участке). Средства резервируются под заказ. 2. **Служба кооператива** закрывает цикл сбора заявок: если набран минимальный порог — заказы объединяются в одну заявку поставщику; если нет — все заказы отменяются, резерв снимается. 3. **Поставщик** акцептует консолидированную заявку (или отказывается — тогда заказы отменяются). 4. **Поставщик** собирает партию точно по составу заявки и выбирает доставку (самовывоз / экспедитор). 5. **Поставщик** передаёт партию на участок и ставит первую подпись на акте приёмки. 6. **Председатель** ставит вторую подпись — поставка принята, имущество на складе, возникает обязательство оплатить поставщику. - 6a. Кооператив инициирует выплату; у кассира появляется задача провести банковский перевод. - 6b. Кассир подтверждает перевод (или отклоняет) — обязательство закрывается (остаётся открытым при отказе). 7. **Председатель** открывает выдачу. 8. **Заказчик** забирает имущество, ставит финальную подпись. При расхождении факт/заказ сумма заранее корректируется. Заказ закрыт, открыто гарантийное окно. ### 2. Проводки (Дт/Кт) - **Создание заказа** — Дт 80 (Паевой фонд) / Кт 86 (Целевое финансирование): резерв средств под заказ. - **Отмена / недовыдача** — без проводки (движение внутри счёта 86). - **Доплата по факту** — Дт 80 / Кт 86: доп. паевой взнос переходит в целевое финансирование. - **Приёмка имущества** (вторая подпись председателя) — Дт 10 (Материалы) / Кт 86. - **Оплата поставщику** (после подтверждения кассиром) — Дт 86 / Кт 51 (Расчётный счёт). - **Выдача имущества** (финальная подпись заказчика) — Дт 86 / Кт 10. ### 3. Документы - **Акт приёма-передачи (приёмка кооперативом)** — две подписи: поставщик (передал), затем председатель (принял). Шаги 5 и 6. - **Акт приёма-передачи (выдача заказчику)** — две подписи: председатель (открыл выдачу), затем заказчик (получил). Шаги 7 и 8. - **Товарно-транспортная накладная** — при доставке через экспедитора, подписи вне блокчейна (поставщик, председатель, экспедитор). ### 4. Движение по кошелькам - **Паевой взнос → резерв под заказ**: при создании заказа средства заказчика блокируются под конкретный заказ (недоступны до конца цикла). - **Резерв → членский кошелёк Стола заказов**: при отмене заказа или недовыдаче средства возвращаются и остаются в программе на следующие заказы. - **Паевой взнос → членский кошелёк Стола заказов**: при доплате за большее количество (добирает резерв; напрямую с паевого не списывается). - **Резерв списывается**: при выдаче имущества зарезервированная сумма уходит как целевой членский взнос. - **Оплата поставщику** идёт с расчётного счёта кооператива (бухгалтерский счёт, не кошелёк) после фактического банковского перевода. **⚠️ На ревью (НЕ правил):** - CRITICAL drift (autofixable=false, НЕ применял): action marketplace::expirecycle — в коде реальное имя expireorder (src/p.mkt.supply/expireorder.cpp). Требует решения: переименовать в стандарте или подтвердить расхождение. - CRITICAL drift: action marketplace::acceptbatch — в коде acceptorder (active→accepted, без ledger2). - CRITICAL drift: action marketplace::declinebatch — в коде declineorder (active→cancelled, o.mkt.unlock). - CRITICAL drift: action marketplace::prepship и привязанный документ ТТН (registry_id 0) — в коде отсутствуют; комментарий в table_marketplace_orders.hpp фиксирует, что шага «готов отгрузить» нет, accepted→supply_prepared идёт сразу через signsupp. Возможно весь шаг prepship и состояние ship_ready выдуманы. - CRITICAL drift: state ship_ready отсутствует в namespace OrderStatus (реальные: active/cancelled/accepted/supplyprep/acceptcoop/readyrecv/received). Висит между accepted и supply_prepared. - WARNING: documents registry_id 702/802 кодом не закрепляются — в .cpp нет Document::validate_registry_id, только verify_document_or_fail; значения ведутся по note методолога. Реестровые папки 702.AssetContributionAct/802.ReturnByAssetAct существуют, но привязки в коде нет. - INFO (сужение графа, не правил): payout/payconfirm/paydecline в коде возможны не только в accepted_to_coop, но и в ready_to_receive/received (status==ACCEPTED_TO_COOP||READY_TO_RECEIVE||RECEIVED). Стандарт описывает триплет только на accepted_to_coop. - INFO: описание o.mkt.purch ранее говорило «срабатывает атомарно с o.mkt.payout» — в коде o.mkt.payout применяется отдельно в callback payconfirm (lazy, L12). Текст исправлен на lazy-модель; смысловой дрейф отмечаю для подтверждения. - SOFT (не правил, для ревью): проводки Дт/Кт и фразы «оба кошелька на счёте 86», «упрощённая модель без счёта 60» оставлены в descriptions — понятны бухгалтеру, но при желании можно вынести в отдельную бух-секцию. - SOFT: backend как бизнес-роль («Автоматизированная служба кооператива») — проверить, устраивает ли формулировка методолога, или роль трактуется как чисто техническая. --- ### `p.mkt.wroff.standard.yaml` — Утилизация скоропорта ## Утилизация скоропорта Периодическое списание со склада участка имущества, которое физически пропало или стало непригодным к выдаче заказчику (просрочка, повреждения, малоценка). ### 1. Последовательность действий 1. **Председатель** — по расписанию (по умолчанию раз в месяц, дату согласует бухгалтер) опрашивает склады участков, собирает позиции к списанию, подписывает заявление и вносит проект на рассмотрение совета. 2. **Совет** — рассматривает заявление по типовому процессу решения совета; при положительном решении председатель подписывает протокол, при отрицательном — проект отклоняется. 3. **Председатель (от имени кооператива)** — по принятому протоколу списывает каждую позицию проекта со склада. Когда списаны все позиции — проект завершён. ### 2. Проводки | Когда | Дт | Кт | Смысл | |---|---|---|---| | Шаг 3, по каждой позиции | **86** (Целевое финансирование) | **10** (Материалы) | Стоимость выбывающего имущества относится на расход целевых средств программы; имущество уходит из учёта как безвозвратные потери. | ### 3. Документы - **Заявление о списании скоропорта** — подписывает председатель на шаге 1 перед внесением проекта на совет (список: участок, наименование, количество, сумма, причина). - **Протокол совета о списании скоропорта** — подписывает председатель на шаге 2 после положительного решения совета (документ типового процесса решения совета). ### 4. Движение по кошелькам **Нет.** Это чисто бухгалтерское событие: имущество выбывает со склада и относится на расход целевых средств программы. Кошельки заказчиков и кооператива не двигаются, ничего не блокируется. Имущество учитывается отдельно по каждому участку. **⚠️ На ревью (НЕ правил):** - actions[0].amount_ref / поле суммы: проверено и исправлено по коду; но дрейф имени поля (cost→amount) стоит подтвердить ревьюером, что struct wroff_item в table_marketplace_writeoff_proposals.hpp действительно field amount (findings autofixable=true, применено механически). - guard/actor: в transitions actor переходов ∅→proposed и authorized→executed указан chairman, а propwroff.cpp/execwroff.cpp используют require_auth(coopname) + Branch::is_user_authorized(signer). Расхождение терминологическое (бизнес-роль vs техническая авторизация) — оставлено как есть, нужно решение ревьюера (autofixable=false). - documents: контракт p.mkt.wroff не вызывает Document::validate_registry_id для 1106/1105 в самих экшнах — валидация делегирована типовому процессу решения совета. По дизайну, но отметить на ревью (autofixable=false). - SOFT-замечания языка (не применял, на ревью PR): header «Модель кошельков» с жаргоном «per-КУ субсчета» (строки 17-20); служебный блок «Источники правды в коде» с техно-именами OPERATION_REGISTRY/processes::marketplace::WRITEOFF/o.mkt.wroff (строки 27-34); комментарий «Имена actions ≤12 символов eosio::name» (строки 69-73); комментарий states с «таблица wroffprops, scope=coopname» (строки 99-104); documents[].note с путями-источниками components/cooptypes/.../1106 и 1105; operations[0].description с дублированием проводки и калькой «несколько последовательных операций в одной транзакции»; inline-метки L1/L2/L3 в операции. --- ## Контракт soviet — стандартов 3 ### `sov.authpkg.standard.yaml` — Автоматизированное принятие решений советом ## Автоматизированное принятие решений советом Общий механизм: любой процесс (приём пайщика, заём, расход, инвестиция, общее собрание, маркетплейс), которому нужно согласие совета, передаёт совету пакет документов; совет голосует; согласие (или отказ) автоматически возвращается в исходный процесс. ### 1. Последовательность действий 1. **Исходный процесс → совет.** Процесс передаёт пакет документов и заранее указывает, что произойдёт при согласии и при отказе совета. Повестка поступает в совет, начинается голосование. 2. **Члены совета → голосование.** Голосуют «за»/«против», могут отозвать голос до окончания. При большинстве «за» решение считается одобренным. 3. **Председатель → подписывает протокол.** Решение становится готовым к исполнению. 4. **Любой пайщик → исполнение.** Согласие совета применяется к исходному процессу, и он продолжается дальше. Ветки: большинство «против» — исходный процесс получает отказ; не уложились в срок — решение отменяется как просроченное, согласия нет. ### 2. Проводки Нет. Сам процесс голосования не двигает средства по кошелькам и не создаёт бухгалтерских проводок (Дт/Кт). Все движения средств возникают уже внутри исходных процессов после получения согласия совета — и описаны в их собственных стандартах. ### 3. Документы - **Протокол решения совета** — подписывает председатель на шаге 3 (подписание протокола). Хранится при записи решения. - Документ повестки приходит из исходного процесса — у каждого свой (заявление о приёме, заявление на заём и т. д.); здесь не фиксируется. В отдельных процессах вместо общего протокола может применяться особый шаблон (например, «Решение совета о приёме пайщика») — это задаёт родительский стандарт. ### 4. Движение по кошелькам Нет. На этом процессе средства по кошелькам не двигаются и ничего не блокируется — он только фиксирует согласие/отказ совета. Любые движения средств происходят в исходных процессах после получения согласия. **⚠️ На ревью (НЕ правил):** - [critical, autofixable=false] transitions[] pending→rejected по soviet::voteagainst: в коде voteagainst.cpp перехода нет — add_vote_against лишь делает votes_against.push_back(username), не считает консенсус и не переводит решение в отказ. Фактический путь отказа — cancelexprd (истёк срок, erase) либо decline_callback внутри effect на exec. Транзишен описывает несуществующую в коде смену статуса. Гард «Большинство голосов против» в коде отсутствует. Требует решения ревьюера: убрать переход / переразметить как virtual через просрочку, или это намеренная модель. - [warning, autofixable=false] documents[0] registry_id=600: authorize.cpp проверяет document только через verify_document_or_fail(document), БЕЗ Document::validate_registry_id(document, 600) — код не пинит реестр 600, принимает документ любого реестра. Стандарт декларирует жёсткое закрепление id, код не валидирует. Оставлено как есть (структурное поле); решение — ослабить формулировку привязки или закрепить валидацию в коде. - [info, autofixable=false] states[] (pending/approved/authorized/executed/rejected) не сверяемы 1:1 с кодом: у soviet::decision нет namespace Status; статусы синтетические (флаги validated/approved/authorized + erase записи). Это моделирование, не зеркало enum. Расхождением кода не является, отмечено для ревью. - [info, autofixable=false] exec не вызывает обобщённый confirm/decline callback по полям, а делает hardcode-диспетч if/else по decision->type (withdraw_effect/subaccum_effect/freedecision_effect/authorize_action_effect); erase записи — внутри effect, не в exec. По смыслу совпадает со стандартом, отмечено для точности. --- ### `sov.decision.standard.yaml` — Принятие свободного решения советом ## Принятие свободного решения советом Путь, по которому совет голосует по произвольному вопросу повестки: инициатор сам формирует и подаёт повестку, совет голосует, председатель подписывает протокол. Для решений, не привязанных к стандартизованному процессу. ### 1. Последовательность действий 1. **Инициатор (член совета или пайщик)** → подаёт документ повестки. Вопрос ставится на голосование, членов совета оповещают. 2. **Члены совета** → голосуют «за» / «против» (голос можно отозвать*). При большинстве «за» решение считается одобренным. 3. **Председатель** → подписывает протокол решения. Решение готово к исполнению. 4. **Любой пайщик / системный триггер** → исполняет решение: факт принятия фиксируется, запись о голосовании закрывается. *Примечание для ревью: в коде отзыв голоса сейчас фактически заблокирован — см. unresolved (дрейф cancelvote).* **Ветки:** при большинстве «против» — решение отклонено, протокол не оформляется. При просрочке — любой член совета может отменить решение как просроченное (закрывается без исполнения). ### 2. Проводки Нет. Свободное решение само по себе не двигает средства и не делает бухгалтерских проводок — это путь принятия решения. Конкретные финансовые последствия (если совет так решил) оформляются отдельным процессом вне рамок этого стандарта. ### 3. Документы | Шаг | Документ | Подписывает | |---|---|---| | 1. Подача повестки | Предложение повестки дня собрания совета | Инициатор | | 3. Утверждение | Протокол решения совета | Председатель | Второй документ (протокол) подписывается председателем на шаге утверждения и прикладывается к решению. ### 4. Движение по кошелькам Нет. Процесс не блокирует и не перемещает средства ни по каким кошелькам. Внешний эффект свободного решения — фиксация самого факта решения; любое конкретное действие выполняется вне этого процесса (свободная воля совета). **⚠️ На ревью (НЕ правил):** - ДРЕЙФ (autofixable=false, на ревью): actions[soviet::cancelvote] — в коде src/vote/cancelvote.cpp вторая строка тела eosio::check(false, «Отмена голоса запрещена»), отзыв голоса жёстко запрещён и недостижим. Стандарт же описывает cancelvote как рабочее действие и упоминает его в сценарии («голос можно отозвать»). Поведенческий дрейф: либо вернуть отзыв голоса в коде, либо убрать действие из стандарта. Не правил автоматически — нужно решение по сути. - INFO (autofixable=false): у сущности decision нет namespace Decision::Status с enum-константами; статусы (created/approved/authorized/executed/rejected) выводятся из bool approved/authorized и факта наличия/удаления строки. Моделирование в стандарте корректно (rejected помечен kind: virtual), но 1:1 state→константа в коде отсутствует. - INFO (autofixable=false): привязка документов к экшнам не подкреплена validate_registry_id в .cpp — freedecision.cpp не валидирует registry_id 599, authorize.cpp зовёт generic verify_document_or_fail без проверки id 600. Покрытие формально 1:1, но проверки конкретного registry_id на уровне контракта нет. - SOFT (на ревью, не правил): шапка-комментарий с путями к исходникам (строки 8-15) — адресована разработчику, а не бизнес-читателю; кандидат на удаление из стандарта. - SOFT: header (строка 6) «формируются контрактом-инициатором — см. sov.authpkg» — техническая ссылка; предложено заменить на «…автоматически в рамках другого, стандартизованного процесса». - SOFT: votefor.purpose «статус решения переводится в approved» и voteagainst.purpose «переходит в статус rejected» — мягко рекомендовано «считается одобренным/отклонённым». - SOFT: alternatives[Отклонение голосованием].description «помечается как rejected» — мягкая правка на «считается отклонённым». - SOFT: documents[].stored_in (decisions.statement / decisions.authorization) — техническая деталь хранения; рассмотреть удаление как служебного поля. --- ### `sov.selectbranch.standard.yaml` — Прикрепление пайщика к кооперативному участку ## Прикрепление пайщика к кооперативному участку Простой одношаговый процесс. Пайщик выбирает кооперативный участок (территориальную единицу кооператива), к которому будет относиться. Заявление принимается сразу, без отдельного решения совета. ### 1. Последовательность действий 1. **Пайщик** оформляет и подписывает (ЭЦП) заявление о выборе кооперативного участка. 2. **Кооператив** проверяет: пайщик состоит в кооперативе и выбранный участок существует. 3. **Кооператив** закрепляет пайщика за выбранным участком и сразу фиксирует заявление в реестре документов. Итог: пайщик прикреплён к участку (конечное состояние). ### 2. Проводки Нет. Процесс нефинансовый — движения средств и бухгалтерских проводок не порождает. ### 3. Документы - **Заявление пайщика о выборе кооперативного участка** — подписывает пайщик на шаге 1. Фиксируется в реестре документов кооператива. ### 4. Движение по кошелькам Нет. Кошельки не затрагиваются, ничего не блокируется и не переводится. **⚠️ На ревью (НЕ правил):** - header-комментарий (строки 3-9) содержит «action», «реализован в контракте Soviet», имя реестра «participants» и путь к .cpp в прозе — soft-замечание, не автофикшу; на PR-ревью переформулировать в бизнес-пояснение, путь оставить только в structured entity_source. - Дрейф (state, warning, autofixable=false): у сущности participant нет namespace Status; реальные значения status в коде — свободные литералы accepted/blocked, значения «attached» нет. selectbranch меняет braname, а не status — состояние «attached» в стандарте описывает факт заполнения braname, не статус сущности. Требует решения методолога: оставить как «логическое состояние» или переописать. - Дрейф (document, info, autofixable=false): registry_id=101 в коде не enforced — selectbranch.cpp вызывает verify_document_or_fail(document) (только подписи), validate_registry_id(…, 101) не вызывается. Привязка 101 — договорённость стандарта, а не проверка контракта; пометить на ревью. --- ## Контракт registrator — стандартов 2 ### `p.reg.accept.standard.yaml` — Приём пайщика ## Приём пайщика Корневой процесс вступления человека или организации в кооператив. ### 1. Последовательность действий 1. **Кандидат** подаёт заявление о вступлении, выбирает кооперативный участок и подписывает ЭЦП → кооператив открывает заявку и выставляет счёт на оплату регистрационного взноса (вступительный + минимальный паевой). Совет получает оповещение. 2. **Кассир** сверяет поступление денег с выставленным счётом и подтверждает оплату → заявка идёт на рассмотрение совета. Взносы пока на учёт не поставлены. 3. **Совет** принимает положительное решение → кандидат становится активным пайщиком, включается в список членов, и оба взноса одновременно встают на учёт. Ветки отказа: кассир может отклонить оплату (если деньги не пришли/отозваны), совет может отказать в приёме — в обоих случаях заявка закрывается, взносы на учёт не ставятся, возврат уже уплаченных денег оформляется отдельной процедурой. ### 2. Проводки (на шаге 3, при одобрении совета) - **Дт 51 / Кт 86** — вступительный взнос пайщика (целевое поступление в кооперативный фонд). - **Дт 51 / Кт 80** — минимальный паевой взнос при регистрации (в паевой фонд кооператива). Обе проводки делаются одновременно в момент решения совета о приёме, не раньше. ### 3. Документы и подписи - **Заявление на вступление в кооператив** — подписывает кандидат на шаге 1. - **Решение совета о приёме пайщика** — подписывает совет на шаге 3 (закрывающий шаг). ### 4. Движение по кошелькам - На шаге одобрения советом средства встают на учёт: вступительный взнос — на кошелёк вступительных взносов; минимальный паевой — на кошелёк минимальных паевых взносов. - До решения совета (шаги 1–2) деньги числятся как оплаченные, но ни на один кошелёк ещё не зачислены. - При отказе (кассира или совета) на кошельки ничего не зачисляется. **⚠️ На ревью (НЕ правил):** - [document, autofixable=false] registry_id=100 (reguser/statement) и registry_id=501 (confirmreg/authorization) в YAML не закреплены кодом: reguser.cpp:55 делает только verify_document_or_fail(statement) без validate_registry_id, confirmreg.cpp не валидирует параметр authorization вовсе. ID правдоподобны и подкреплены реестром, но не подтверждены кодом — оставлено как есть, нужно ревью/решение по привязке. - [soft] Шапка: слова «Манифест», «tagline» — заменить на человеческое «к каждому разделу короткая суть одной строкой и развёрнутое пояснение». - [soft] process_type как термин встречался в прозаических комментариях — соответствующие комментарии уже переписаны; само поле process_type: p.reg.accept оставлено (структурный идентификатор). - [soft] entity: «registrator::candidate → registrator::account» — структурное поле; рядом есть человеческое entity_human «Кандидат → пайщик», при желании очистить. - [soft] documents[].stored_in (строка про authorization): «(authorization — в параметре действия, не хранится в candidates после удаления записи)» — прозаическое пояснение с техническими словами; заменить на бизнес-смысл или оставить пустым. - [soft] «выставляет счёт» в purpose/scenario — легитимная идиома «счёт на оплату»; при желании уточнить «счёт на оплату регистрационного взноса», чтобы не путать со счетами 80/86. --- ### `reg.coop.standard.yaml` — Присоединение к платформе кооперативной экономики ## Присоединение к платформе кооперативной экономики Кооператив подключается к цифровой платформе «Кооперативная Экономика»: председатель подписывает соглашение о присоединении, после чего часть паевого взноса конвертируется в членский взнос платформы (AXON) — оплату её ресурсов (документооборот, операции, хранение). ### 1. Последовательность действий 1. **Председатель** подписывает соглашение о присоединении и направляет его регистратору. Кооператив регистрируется на платформе в статусе «Соглашение подписано» и ожидает авторизации совета. 2. **Совет провайдера** выполняет конвертацию: часть паевого взноса переводится в членский взнос платформы (AXON) по курсу 10:1. Кооператив становится активным членом платформы. > Замечание ревью: по факту кода статус «активен» выставляет отдельное действие регистратора (stcoopstatus), а не конвертация — см. unresolved. ### 2. Проводки | Когда | Дт | Кт | Смысл | |---|---|---|---| | Конвертация паевого взноса в членский | 80 (Паевой фонд) | 86 (Целевое финансирование) | Часть паевого капитала кооператива превращается в целевые поступления платформы | ### 3. Документы | Шаг | Документ | Кто подписывает | |---|---|---| | 1 | Соглашение (оферта) о присоединении к платформе | Председатель | | 2 | Заявление о конвертации паевого взноса в членский взнос | Председатель | Оба документа сохраняются в реестре документов платформы. ### 4. Движение по кошелькам - При конвертации: средства списываются из **паевого фонда кооператива** и зачисляются в **фонд членских (делегатских) взносов платформы**. - После перевода кооперативу начисляется членский взнос платформы (AXON). - Условие: в паевом фонде кооператива достаточно средств для конвертации. **⚠️ На ревью (НЕ правил):** - [critical, autofixable=false] transitions[1] (pending→active, soviet::converttoaxn): по коду converttoaxn НЕ меняет cooperatives2.status — статус active реально выставляет registrator::stcoopstatus(status=active). Граф состояний приписывает переход не тому действию. Требует решения: либо добавить действие stcoopstatus в стандарт, либо переосмыслить связку. Не правил — возможный баг/семантика. - [warning, autofixable=false] documents[0] (registry_id=50): regcoop.cpp сохраняет document без validate_registry_id/verify_document_or_fail — кодовой привязки к реестру 50 нет (в отличие от converttoaxn.cpp, который явно проверяет registry_id=51). registry_id=50 в structured-поле документа может не отражать код. На ревью PR. - [info, autofixable=false] states: в коде существует статус blocked (stcoopstatus.cpp: active|blocked|pending), не отражённый в стандарте. Для фокусного стандарта присоединения не обязателен — отметка для ревью. - [soft] actions[converttoaxn].purpose и operations[o.sov.axncnv].description: проводка «Дт 80 / Кт 86» в прозе дублирует раздел операций (L1). Можно опустить — оставлено на усмотрение ревьюера. - [soft] scenario.steps[2].pre[0]: «Кооператив в статусе `pending`» — сырой статус; можно заменить на человеческое «Соглашение подписано». Оставлено. --- ## Контракт wallet — стандартов 2 ### `p.wal.depo.standard.yaml` — Внесение паевого взноса ## Внесение паевого взноса Пайщик пополняет свой **паевой кошелёк** деньгами. Документ не оформляется — взнос подтверждается самим фактом платежа через кассира. ### 1. Последовательность действий 1. **Пайщик** инициирует внесение взноса с указанием суммы → создаётся заявка «ожидает оплаты», пайщику выставляется **платёжный счёт**. 2. Пайщик оплачивает счёт; деньги поступают на расчётный счёт кооператива. 3. **Кассир** подтверждает поступление платежа → сумма зачисляется на паевой кошелёк пайщика, заявка закрывается («Взнос учтён»). - *Альтернатива:* платёж не прошёл / отменён → кассир отклоняет оплату, заявка закрывается, взнос не зачисляется. Пайщик может подать заявку заново. ### 2. Проводки | Когда | Дебет | Кредит | Смысл | |---|---|---|---| | При подтверждении оплаты кассиром | **Дт 51** (расчётный счёт) | **Кт 80** (паевой фонд / складочный капитал) | Деньги пайщика поступили на расчётный счёт и увеличили складочный капитал кооператива | ### 3. Документы Не подписываются. Взнос не требует договора — основание — сам факт платежа. ### 4. Движение по кошелькам - **Зачисление взноса:** на паевой кошелёк пайщика поступает сумма взноса (первичный вход средств). Списаний и блокировок нет. - Средства становятся доступны пайщику для дальнейших кооперативных процессов — займов, инвестиций, поставок, выходов. - *Напоминание:* «платёжный счёт» и «расчётный счёт 51» — это счета (документ-инвойс и бухгалтерский), а не кошелёк; зачисление взноса идёт именно на **паевой кошелёк**. **⚠️ На ревью (НЕ правил):** - Findings сверки с кодом пусты — дрейфа structured↔код не обнаружено. - SOFT (стр. 11-15): блок «Источники правды в коде» в шапке содержит ledger2/operations.hpp и o.wal.depcpl как технический указатель для разработчика. Аудит классифицировал как допустимый; на ревью решить — оставить пути к файлам без дублирования имён операций или удалить блок целиком. - SOFT (states[1], стр. 75): номера счетов «(счета 51 / 80)» в описании состояния дублируют проводку §6 — можно опустить или оставить как пояснение бухгалтеру. - SOFT (guards[0] перехода ∅→pending, стр. 90): «Пайщик имеет статус active» — техно-значение «active»; можно заменить на «действующий участник», но это guard-поле (semi-structured), оставил без правки для ревью. - SOFT (operations[0].description, стр. 174-175): проводка Дт 51/Кт 80 в прозе дублирует L1-поля debit/credit; текст корректен (51 расчётный, 80 паевой фонд), можно оставить как пояснение бухгалтеру. --- ### `p.wal.wthdrw.standard.yaml` — Возврат паевого взноса ## Возврат паевого взноса Пайщик получает обратно ранее внесённый паевой взнос деньгами. Обратный процесс к внесению взноса. ### 1. Последовательность действий 1. **Пайщик** подаёт и подписывает заявление на возврат → заявка регистрируется, сумма резервируется, вопрос выносится в совет. 2. **Совет** авторизует выплату единым решением → в платёжную систему уходит поручение на выплату пайщику. 3. **Кассир (оператор платёжной системы)** подтверждает выплату → деньги ушли пайщику банковским переводом, заявка закрывается. - *Альтернатива:* отказ совета или платёжной системы на любом шаге до выплаты → зарезервированная сумма возвращается пайщику, заявка закрывается. ### 2. Проводки - Резервирование (шаг 1) и возврат при отказе — **без проводки** (движение по кошелькам, бухгалтерский счёт не меняется). - Подтверждение выплаты (шаг 3): **Дт 80 «Паевой фонд» / Кт 51 «Расчётный счёт»** — паевой фонд уменьшился, деньги ушли с расчётного счёта пайщику. ### 3. Документы - **Шаг 1:** «Заявление на возврат паевого взноса денежными средствами» — подписывает пайщик. - **Шаг 2:** «Решение совета о возврате паевого взноса (авторизация на выплату)» — подписывает совет. ### 4. Движение по кошелькам - **Шаг 1:** сумма возврата переводится с паевого кошелька пайщика → в кошелёк-резерв выплат (резервируется). - **Шаг 3 (выплата):** сумма списывается из кошелька-резерва выплат → уходит пайщику банковским переводом (получателя на цепи нет). - **Отказ:** зарезервированная сумма возвращается из кошелька-резерва выплат → обратно на паевой кошелёк пайщика. *(Кошелёк ≠ бухгалтерский счёт: счета 80/51 — только в проводке шага 3; движение между кошельками проводок не создаёт.)* **⚠️ На ревью (НЕ правил):** - soft: header comment (строки 12-18) — блок технических ссылок на код (o.wal.wthcpl, ledger2, processes::wallet::WITHDRAW) избыточен для нетехнаря; уместен как служебная сноска, но можно вынести/сократить — на усмотрение ревью - soft: operations[0].human_name (o.wal.wthreq) «Резервирование паевого под запрос на возврат» — допустимо; яснее «Резервирование суммы возврата на кошельке-резерве выплат» - soft: operations[2] inline-комментарий «# кошелёк-резерв возвратов» (строка 266) — можно унифицировать с прозой на «кошелёк-резерв выплат» - soft: transitions[0].guards «withdraw_hash уникален» — можно очеловечить до «Заявка на возврат не дублирует уже существующую» - soft: проводки Дт 80 / Кт 51 в action[2].purpose и state completed описаны как дублирующие L1 — рассмотреть удаление из прозы (оставлены, т.к. бухгалтеру допустимы) - info/autofixable=false (НЕ применено, баг/семантика кода — для ревью): (1) registry_id 900/901 — в .cpp нет validate_registry_id, привязка id→документ on-chain не проверяется (только хранением); (2) устаревшие комментарии в createwthd.cpp/declinewthd.cpp пишут BLOCK/UNBLOCK на w.wal.share, тогда как реальные операции — TRANSFER (стандарт описывает корректную TRANSFER-механику); (3) у withdraw нет Status-namespace, status — свободный eosio::name; completed/removed в коде не хранятся (erase) — в стандарте корректно помечены final/virtual --- ## Контракт meet — стандартов 1 ### `meet.hold.standard.yaml` — Проведение общего собрания пайщиков ## Проведение общего собрания пайщиков Высший орган управления кооперативом в действии: от подачи повестки и авторизации советом до сбора бюллетеней и подписи протокола. При недостижении кворума собрание перезапускается с понижением требования к кворуму. ### 1. Последовательность действий 1. **Пайщик-инициатор** → формирует повестку (до 10 вопросов), назначает председателя и секретаря, задаёт окно голосования (открытие не ранее чем через 15 дней), подписывает предложение повестки. Статус → «Повестка подана». 2. **Совет** → принимает решение о созыве (типовой автоматизированный процесс совета) и подписывает авторизацию. Статус → «Совет авторизовал». 3. **Пайщики** → подписывают уведомления о собрании (фиксируются в списке оповещённых). Идёт параллельно с голосованием. 4. **Пайщики** → в окне голосования подписывают бюллетени по всем вопросам (за/против/воздержался); пересчитывается достигнутый процент кворума. 5. **Секретарь** → после закрытия окна и при достигнутом кворуме подписывает протокол. Статус → «Подписано секретарём». 6. **Председатель** → подписывает протокол; итог по каждому вопросу подводится по правилу большинства (50% + 1 голос). Статус → «Собрание состоялось», решения приняты. - **Альтернатива (перезапуск):** если кворум не собран, инициатор подаёт новую повестку с новыми датами — цикл растёт, требование к кворуму понижается, процесс возвращается на шаг авторизации советом. ### 2. Проводки Нет. Общее собрание не двигает кошельки и не делает бухгалтерских проводок — принятые решения исполняются вне этого процесса. ### 3. Документы | Шаг | Документ | Подписывает | |---|---|---| | 1. Создание повестки | Предложение повестки дня общего собрания | Пайщик-инициатор | | 2. Авторизация | Решение совета о созыве общего собрания | Совет | | 3. Оповещение | Уведомление о проведении общего собрания | Пайщик | | 4. Голосование | Заявление с бюллетенем для голосования | Пайщик | | 5. Подпись секретаря | Протокол решения (подпись секретаря) | Секретарь | | 6. Подпись председателя | Протокол решения (подпись председателя) | Секретарь + Председатель | | Перезапуск | Предложение повестки (повторное) | Пайщик-инициатор | Протокол секретарь подписывает первым, председатель накладывает свою подпись на тот же протокол вторым — собрание становится состоявшимся только после обеих подписей. ### 4. Движение по кошелькам Нет. Средства по кошелькам в рамках этого процесса не движутся и ничего не блокируется. **⚠️ На ревью (НЕ правил):** - Граф: статус onrestart не имеет явного исходящего перехода в transitions[] (возврат к authorized идёт через authmeet, чей guard принимает status==onrestart||created); связность по факту есть, в YAML переход onrestart→authorized неявный, virtual:true смягчает. autofixable=false — на ревью. - Документы: привязка через verify_document_or_fail(...), а не Document::validate_registry_id(<param>,<id>); жёсткой проверки registry_id в сигнатуре нет, но покрытие 300-304 1:1 подтверждено папками реестра. autofixable=false — отмечен способ привязки. - soft: header comment (строки 8-16) — блок «Источники в коде» с путями .cpp читателю не нужен; пользователь предложил убрать, но это soft — оставил для ревью на PR. - soft: статус-имена `created`/`onrestart`/`authorized`/`preclosed`/`closed` в прозе actions[0..6].purpose, states[0].description, transitions[1].guards, scenario step1.post[0]/step1.pre/alternatives — предложены человеческие названия, но soft. - soft: actions[3].purpose (vote) и scenario step4.description — «контракт обновляет счётчики» предложено смягчить до «голоса учитываются». - soft: transitions[3].guards[2] и scenario step4.description — `[open_at..close_at]` предложено заменить на «окно голосования». - soft: transitions[0].guards (createmeet) — `initiator/presider/secretary + coopname` технические идентификаторы участников; аудит их не флагнул как hard, но это технический хвост — на усмотрение ревью. - soft: documents[2]/[3].stored_in: «documents-registry (по hash собрания)» — место хранения; если показывается читателю, заменить на «реестр документов собрания», иначе оставить как идентификатор. ---
claude added 1 commit 2026-06-04 06:37:48 +00:00
Workflow coop-standards-check: техно-хвосты (идентификаторы кошельков/операций,
ledger2, проводки-калька) убраны из прозы 4 capital-стандартов; structured-поля
(Дт/Кт, кошельки, ledger_code) не тронуты. Спорное (возможные баги кода,
семантика статусов invested/commit_*) НЕ правил — в теле PR на ревью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 06:48:28 +00:00
Путаница бухгалтерского счёта и ledger2-кошелька в прозе: «перемещение между
счётами»/«на счёт программы» → «между кошельками»/«на кошелёк программы»
(движение без проводки = по кошелькам). В p.cap.invest заодно исправлен неверный
счёт: «деньги на расчётном счёте» → «бухгалтерский счёт не меняется».
Правило зафиксировано в каноне workflow и памяти.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 07:15:12 +00:00
Переделано агентами Opus (предыдущие коммиты — Haiku, доверия нет): техно-хвосты
из прозы, счёт≠кошелёк (в т.ч. ошибка из оригинала p.cap.invest), structured-поля
нетронуты. Спорный дрейф (o.cap.lend в debtpaycnfrm; o.cap.repay triggered_by;
debtpaydcln нооп) — в теле PR на ревью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 07:26:22 +00:00
Workflow coop-standards-check на Opus, 3 стандарта (supply/return/wroff):
техно-хвосты убраны из прозы (callback/gateway::/compensating forward/имена
операций/кошельки), gateway→«система процессинга», backend→«служба кооператива»;
structured-поля не тронуты. Спорное (registry_id 0/800 без validate_registry_id
в коде) — в теле PR на ревью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 07:35:35 +00:00
3 стандарта (authpkg/decision/selectbranch): техно-хвосты (callback/exec/
decision.type/handler/registry_id/whitelist/имена экшнов) убраны из прозы,
structured-поля не тронуты. Дрейф (voteagainst не делает перехода в коде;
registry_id=600 не валидируется в authorize.cpp; синтетические статусы без
namespace Status) — в теле PR на ревью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 07:42:04 +00:00
2 стандарта (p.reg.accept/reg.coop): техно-хвосты убраны из прозы и шапок
(блоки «Источники в коде», имена экшнов/операций/таблиц, registry_id, ledger2,
TRANSFER); structured-поля и проводки (Дт 51/Кт 86, Дт 51/Кт 80, Дт 80/Кт 86)
сохранены. Дрейф: registry_id 100/501/50/51 не валидируются в коде
(verify_document_or_fail без validate_registry_id) — в теле PR на ревью.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 08:00:47 +00:00
2 стандарта (p.wal.depo/p.wal.wthdrw): техно-хвосты убраны из прозы
(Gateway→платёжная система/кассир, enum-имена кошельков SHARE_FUND_PAY/
WITHDRAW_PENDING→человеческие названия, ledger2/callback/имена операций);
structured-поля и проводки (Дт 51/Кт 80, Дт 80/Кт 51) сохранены.
Дрейфа с кодом не найдено.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-04 08:08:41 +00:00
Перечистка точечным перегоном после ужесточения FORBIDDEN: Gateway→платёжная
система/кассир, кошелёк «Выданные займы» без техно-id в прозе. Структурно:
o.cap.lend перенесён с debtauthcnfr на debtpaycnfrm (LEND проводится там по
коду). o.cap.repay (принадлежит p.cap.rid) — оставлен на ревью в теле PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 2 commits 2026-06-04 08:16:44 +00:00
meet.hold: техно-хвосты убраны из прозы (латинские статусы, notified_users,
open_at/close_at, sov.authpkg, newgdecision, quorum_passed), статусы → человеческие
названия; structured-поля не тронуты, operations:[] (собрание не двигает кошельки).
Дрейфа с кодом не найдено.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 07:16:14 +00:00
REPAY триггерится в capital::signact2 (акт-2, процесс p.cap.rid), а не в
debtpaycnfrm (тот эмитит только LEND). Реестр кода (operations.hpp) привязывает
o.cap.repay к processes::capital::RID, code уникален → операция принадлежит
одному процессу. Дубль в p.cap.debt с triggered_by debtpaycnfrm противоречил
коду — удалён, оставлена поясняющая ссылка на p.cap.rid. Заодно поправлен
коммент processes.hpp DEBT (тоже ошибочно включал o.cap.repay).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 07:55:49 +00:00
[15] cancelvote.cpp жёстко запрещён (eosio::check(false, "Отмена голоса
запрещена")) — отзыв голоса недостижим. Убрано действие из стандарта,
ссылка в шапке и прозе «голос можно отозвать».

[8] action marketplace::expirecycle в коде не существует — реальное имя
expireorder (закрытие заказа по таймауту цикла; backend гоняет по каждому
заказу). Переименовано во всех 5 местах (actions/transitions/scenario/
triggered_by).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 08:39:28 +00:00
Приведение стандартов к коду (прав контракт).

[21] reg.coop: статус active кооператива ставит registrator::stcoopstatus,
а не soviet::converttoaxn (тот делает только конвертацию паевого в AXON,
status не трогает — grep по converttoaxn.cpp пусто). Добавлено действие
stcoopstatus как закрывающее, переход pending→active перевешен на него,
converttoaxn оставлен как денежный шаг (operation o.sov.axncnv), scenario
дополнен шагом активации.

[4] p.cap.prop: в таблице program_property одно поле document2 act
(act1pgprp/act2pgprp оба пишут p.act = act). stored_in обоих актов
исправлен с pgproperties.act1/.act2 на pgproperties.act.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 09:09:30 +00:00
submretrn statement: registry_id 800 (старый донорский клиринговый
ReturnByAssetStatement) → 1104 MarketplaceReturnStatement — шаблон членской
модели серии 1100+ «Стола заказов», рядом с актами/ТТН. Заявление существует,
800 не использовать в членской модели.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 09:11:49 +00:00
Убран техно-мусор из note (registry-номера, имена шаблонов, «донор/клиринг»,
TODO про cooptypes/registry) — по правилам /coop-standards прозаические поля
пишутся бизнес-языком для методолога.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude added 1 commit 2026-06-05 10:52:57 +00:00
# Conflicts:
#	components/contracts/cpp/marketplace/p.mkt.return.standard.yaml
ant merged commit 6f248940e1 into marketplace2 2026-06-05 11:01:36 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: C9S/mono#79