coopops 832888051f
CI / build (push) Failing after 8s
[794-5][@ant] fix: канонизация регистров хэш-цепочки (C3/C4) + UTC для C6 — подпись проходит проверку
Хэш-цепочка SDK склеивает звенья в РАЗНЫХ регистрах (Crypto.sha256 → строчные
meta_hash/hash; doc_hash из фабрики → ПРОПИСНОЙ), а `.sig` хранит их в едином
(часто верхнем) регистре. Верификатор склеивал сырые строки .sig → C3/C4 падали
на валидных документах.

- C3: composite = SHA-256(meta_hash.toLowerCase + doc_hash.toUpperCase).
- C4: signed_hash = SHA-256(hash.toLowerCase + signed_at[без мс/Z]); SDK берёт
  signed_at как toISOString().split('.')[0], а .sig кладёт с `.000`.
- C6: signed_at без таймзоны → роут с format:date-time отдавал HTTP 400; на фронте
  помечаем `Z` (signed_at семантически UTC).

Регистры и формат signed_at выведены из исходников SDK (Document/Crypto) и
ДОКАЗАНЫ на реальном .sig: после фикса C1/C3/C4/C5 = PASS (крипто-подпись
verifyDigest валидна). C2 на legacy-доках — отдельный формат meta, не этот фикс.
2026-06-03 17:48:11 +00:00

Верификатор документов Coopenomics v1

Монорепа доказательного верификатора документов: проверка целостности, криптоподписи (secp256k1/SHA-256) и исторической привязки ключа к аккаунту в блокчейне Coopenomics.

Структура (pnpm workspace)

Пакет Назначение
packages/shared (@verifier/shared) Контракт .sig v2.0 + чистые проверки C1–C5 (браузер + Node). Не публикуется.
apps/api (@verifier/api) Fastify + Kysely + Postgres. Demux-индексер permissions (native-delta из @coopenomics/parser2) + REST /v1/active-permission/*.
apps/spa (@verifier/spa) Vue 3 + Vite + Tailwind v4 + Reka UI. Загрузка PDF+.sig/ZIP, оркестрация C1–C8, вердикт.

Проверки

# Проверка Где
C1 Целостность (SHA-256(pdf) == doc_hash) shared, локально
C2 meta_hash (канонизация JCS) shared, локально
C3 Композитный хэш shared, локально
C4 Подпись secp256k1 shared, локально
C5 Наличие сертификата shared, локально
C6 Историческая привязка ключа к аккаунту api /v1/active-permission/check
C7 Самоподписанность (⚠ предупреждение) spa
C8 Доказательство в цепи (опц.) spa через публичный RPC

Разработка

pnpm install
docker compose up -d        # postgres:5433 + redis:6380
pnpm -r build
pnpm dev:api                # :3030
pnpm dev:spa                # :5173

Дизайн-язык SPA

Минималистичный пространственный дизайн на плоскостях, один ведущий цвет — бордо #9f1239 (бренд кооперативной экономики). Бордо только в chrome; вердикт — отдельная семантика ( зелёный / красный / ⚠ amber). Reka UI + Tailwind v4 + Radix Colors. Эталоны: Linear, Vercel, Raycast, Resend.

Локальный бутстрап против цепи mono-ai-N

Индексация permissions с genesis для проверки C6 на живых документах.

Предусловие: поднята цепь mono (docker compose up в ~/mono-ai-N) — nodeos отдаёт chain API на :8888 и state-history (SHiP) на :8070.

bash deploy/bootstrap/bootstrap-local.sh

Скрипт достаёт chain_id из get_info, поднимает изолированные postgres+redis, parser2 Parser (SHiP→Redis) и verifier-api (consumer+REST, миграции авто), стримит логи.

  • Parser читает SHiP с genesis → Redis Stream; verifier-api потребляет native-delta permission.
  • Прогресс: curl http://localhost:3030/v1/health (current_block/head_block/status).
  • Перезапуск безопасен — parser2 резюмится по позиции в Redis, upsert идемпотентен (натуральный ключ), sync_progress хранит прогресс. Репарсинга с нуля при рестарте нет.
  • Полный реиндекс (осознанно): docker compose -f deploy/bootstrap/docker-compose.bootstrap.yaml down -v.

SPA направить на этот api: VITE_API_BASE=http://localhost:3030.

Деплой

Автономные пайплайны из одной репы: deploy-api.yml (docker image → ssh) и deploy-spa.yml (vite build → nginx static). Деплой одного приложения не триггерит другое.

S
Description
No description provided
Readme 460 KiB
Languages
TypeScript 77.2%
Vue 14.8%
CSS 3.5%
Shell 2.2%
Dockerfile 1.1%
Other 1.2%