Skip to content

docs(plan): структура подчиненности объектов (#1411) - #1422

Merged
ivanarama merged 4 commits into
mainfrom
plan/1411
Sep 17, 2026
Merged

ivanarama merged 4 commits into
mainfrom
plan/1411

Conversation

@ivanarama

Copy link
Copy Markdown
Owner

Технический план

Подготовлен отдельный план выбранного варианта 1 для структуры подчиненности: реальные ссылки из шапок, табличных частей и регистров, fail-closed RBAC/RLS, ленивое дерево и переходы в стандартные формы.

Продуктовый код, зависимости и generated artifacts не изменяются.

Проверки:

  • go run ./tools/plannum
  • go test ./tools/plannum
  • git diff --cached --check

Plan-Issue: #1411
Plan-Path: Plans/171-object-subordination-graph.md

@ivanarama

Copy link
Copy Markdown
Owner Author

Ревью. (круг 1)
Reviewed-SHA: bc0fe12
Outcome-Label: changes-requested
Что меняется: Добавлен технический план этапа 171 для структуры подчинённости объектов: граф фактических ссылок, ленивый UI, RBAC/RLS, срезы реализации и проверки..
Проверено: HEAD bc0fe12 совпадает с lease; diff содержит только новый Plans/171-object-subordination-graph.md (+423 строки).; git diff --check $(git merge-base HEAD origin/main) HEAD — успешно.; go run ./tools/plannum — успешно: 153 плана, номера уникальны.; go test ./tools/plannum — успешно.; go test ./internal/storage -run 'Test(CheckRefs|GetFieldsByIDsFiltered)' — успешно.; go test ./internal/runtime -run TestReceiversOf — успешно.; go test ./internal/configcheck -run 'TestRunFull_RejectsPIIOnTablePartField|TestLintRoles_FieldAccessDiagnostics' — успешно.; GitHub CI на текущем HEAD — все проверки успешны, включая build, lint, postgres-integration, vuln, smoke, e2e, test-windows, launcher-webview-build и bench..
Блокирующее: 1) Plans/171-object-subordination-graph.md:191: контракт лимита противоречит порядку фильтрации. Storage применяет межисточниковый глобальный предел после source-side RLS, а target RBAC/RLS выполняется только затем в UI (строки 210–211). Поэтому недоступные target-записи могут занять первые limit+1 кандидатов, скрыть доступные записи дальше по порядку и дать неверный truncated. Это нарушает обещание считать только доступных соседей (строки 90–91) и обязательный тест «100 доступных плюс скрытые — truncated=false» (строки 303–304). Нужен явно описанный алгоритм, который продолжает детерминированно читать кандидатов до 101 доступного уникального узла (например, пагинация/cursor), либо перенос target-RLS до глобального limit.; 2) Plans/171-object-subordination-graph.md:216: план обещает учитывать mask_*/hide и PII у ссылочных полей табличных частей через synthetic metadata, но текущий контракт это прямо запрещает: metadata.Validate отклоняет pii на поле ТЧ, field_access валидируется только по Entity.Fields, а проектные комментарии фиксируют, что field_access табличные части не адресует. Перечень изменений ограничен storage/UI и не определяет расширение модели ролей, валидации и всех существующих границ чтения ТЧ; следовательно, заявленная гарантия и тест masked/hidden поля ТЧ сейчас нереализуемы безопасно. Нужно либо спроектировать полноценную поддержку field_access/PII для ТЧ во всех read-path, либо убрать это обещание и точно зафиксировать допустимый контракт для ТЧ..
Хвост:

Вердикт: есть замечания.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result publication claimed.

@ivanarama ivanarama added the changes-requested Ревью: есть замечания — фиксер дорабатывает label Sep 9, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result committed.

PP-Fix-Transition: from=bc0fe1254b64be5560bd21580aab77efc6a37a05 review-comment=5599157431 claim=5599157835 epoch-sha256=6a0f08a29c7353a190b3d734645e5ca7ea929b11ad30445ab8b144e449831f1a
Generated-with: Codex
PP-Fix-Transition: from=274ca81d5c30dd88ee31fea5c537a5a232e67c1f review-comment=5602622566 claim=5602623313 epoch-sha256=2c7a7328276800a3d0e728c41a21096da799392dd6fc7aa8d496f111737f8456

Generated-with: Codex
@ivanarama

Copy link
Copy Markdown
Owner Author

Доработал блокирующие замечания ревью PR #1422:

  1. Убрал ранний глобальный limit+1: storage теперь отдаёт детерминированные keyset-страницы, а UI сливает потоки, проверяет target RBAC/RLS и дочитывает их до 101-го доступного уникального узла. Скрытые target-записи не занимают лимит и не дают ложный truncated.
  2. Убрал несуществующую гарантию field_access/PII для полей ТЧ. План теперь явно фиксирует текущую границу: row policy владельца и target-доступ; pii на поле ТЧ остаётся запрещён, а расширение field-level защиты ТЧ вынесено из этапа 171.

Добавил приёмочные сценарии для нескольких cursor-страниц, скрытых targets перед доступными, полной агрегации отношений и точной границы ТЧ. Осознанно не менял продуктовый код и неблокирующий хвост: это plan-PR, в заключении pp:tail=0.

Проверки: git diff --check; go run ./tools/plannum; go test -count=1 ./tools/plannum; go build ./...; go test -count=1 ./....

@ivanarama ivanarama removed the changes-requested Ревью: есть замечания — фиксер дорабатывает label Sep 9, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

Ревью. (круг 2)
Reviewed-SHA: 274ca81
Outcome-Label: changes-requested
Что меняется: Обновлён технический план этапа 171: уточнены cursor-пагинация и подсчёт только доступных соседей, а несуществующая field-level защита полей табличных частей заменена явной row-level границей..
Проверено: HEAD 274ca81 совпадает с lease; diff относительно актуального origin/main a2b3cfd содержит только Plans/171-object-subordination-graph.md (+470 строк).; git diff --check по merge-base с origin/main — успешно.; go run ./tools/plannum — успешно: 153 плана, номера уникальны; go test ./tools/plannum — успешно.; Узкие тесты storage CheckRefs/GetFieldsByIDsFiltered, runtime ReceiversOf и configcheck PII/field_access — успешно.; go test ./... — успешно; go build ./... — успешно.; GitHub CI текущего SHA полностью зелёный: build, lint, postgres-integration, vuln, smoke, e2e, test-windows, launcher-webview-build и bench..
Блокирующее: 1) Plans/171-object-subordination-graph.md:221-254: защита register-ребра проверяет совпавшее ссылочное поле регистра и доступ к документу-узлу, но не требует полного доступа к самой паре регистратора. Узел и URL строятся из recorder/recorder_type (для бухрегистра — регистратор/регистратор_тип), а эти поля адресуются field_access через существующие synthetic metadata. Текущий UI именно поэтому отказывается выбирать движения по регистратору, если любая часть пары замаскирована (internal/ui/handlers_registers.go:150-154). В предложенном контракте роль с mask_* или hide на recorder либо recorder_type всё равно получит точные тип, UUID и URL документа через граф. Нужно до SQL/projection требовать full для обеих компонент регистратора во всех трёх семействах и добавить публичные тесты mask_*/hide для каждой компоненты; ошибка вычисления решения должна закрывать весь ответ..
Хвост:

Вердикт: есть замечания.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result publication claimed.

@ivanarama ivanarama added the changes-requested Ревью: есть замечания — фиксер дорабатывает label Sep 9, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result committed.

@ivanarama

Copy link
Copy Markdown
Owner Author

Доработал блокирующее замечание ревью PR #1422:

  1. Зафиксировал обязательную проверку полного доступа к обеим компонентам регистратора до SQL/projection для регистров накопления, сведений и бухгалтерии.
  2. Добавил публичные HTTP-сценарии mask_*/hide для каждой компоненты каждого семейства и fail-closed проверку ошибок field decision.
  3. Синхронизировал риски и критерии завершения.

Осознанно не менял продуктовый код и неблокирующий хвост: это plan-PR, в заключении pp:tail=0.

Проверки: git diff --check; go run ./tools/plannum; go test -count=1 ./tools/plannum; go build ./...; go test -count=1 ./....

@ivanarama ivanarama removed the changes-requested Ревью: есть замечания — фиксер дорабатывает label Sep 9, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

Ревью. (круг 3)
Reviewed-SHA: c9bbd75
Outcome-Label: reviewed
Что меняется: Технический план 171 описывает выбранный вариант 1 заявки #1411: ленивый граф реальных ссылок шапок, табличных частей и регистров с переходами в карточки. Последняя доработка требует полного доступа к обеим компонентам регистратора до SQL/projection во всех трёх семействах и добавляет соответствующие публичные приёмочные сценарии.
Проверено: Полностью прочитаны diff текущего HEAD c9bbd75, заявка #1411 с решением decision:1 и два предыдущих завершённых круга; проверены source/target RBAC/RLS, keyset-пагинация, подсчёт доступных узлов, граница защиты ТЧ и обе компоненты регистратора; Контракт сопоставлен с CheckRefs, RegisterPredicateEntity/InfoRegisterPredicateEntity/AccountRegisterPredicateEntity, readableFieldsByIDs, maskedRecordLabel и существующей защитой выбора движений по регистратору; В detached worktree точного HEAD: go build ./... — успешно; go run ./tools/plannum — 153 плана, номера уникальны; go test -count=1 ./tools/plannum — успешно; go test -count=1 ./internal/storage -run 'Test(CheckRefs|GetFieldsByIDsFiltered)' и go test -count=1 ./internal/runtime -run TestReceiversOf — успешно; go test -count=1 ./internal/configcheck -run 'TestRunFull_RejectsPIIOnTablePartField|TestLintRoles_FieldAccessDiagnostics' и go test -count=1 ./internal/ui -run 'TestDocumentFormSkipsProtectedRecorderSelection|TestUIRegisterListsApplyFieldMask|TestUI_InfoRegList_MasksAtHandlerBoundaryAndBuildsSafeDetailPayload' — успешно; git diff --check от merge-base a2b3cfd до проверенного HEAD — успешно; PR содержит только план, реализация будущего endpoint ещё не входит в него; Все восемь обязательных CI проверенного HEAD и необязательный bench — SUCCESS.
Блокирующее: нет.
Хвост:

Вердикт: годится к мержу.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result publication claimed.

@ivanarama ivanarama added the reviewed Ревью: блокирующего нет — ждёт ship label Sep 12, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result committed.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: MERGE base synchronization reserved.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: MERGE base synchronization completed.

@ivanarama

Copy link
Copy Markdown
Owner Author

Ревью. (круг 4, интеграционная проверка)
Reviewed-SHA: f948207
Outcome-Label: reviewed

Что меняется: в ветку технического плана подмешан main f9de312. Сам Plans/171-object-subordination-graph.md побайтно совпадает с планом из проверенного c9bbd75. Содержательное основание — успешное ревью исходного HEAD.

Проверено:

  • Два полных последовательных GraphQL snapshot совпали; REST id/node_id согласованы с GraphQL fullDatabaseId/id. Подтверждены каноничные source review/claim/completion 5646908538/5646909140/5646910827, неизменённые intent 5707287501 и done 5707289883, непрерывное разрешение ship, текущий HEAD и epoch. Parents merge-коммита ровно [c9bbd7540d5f7fd9311ac0017c5d70d2fc1939e9, f9de3128184af9ce215f5fd7885397529b104d56]; второй parent совпадает с проверенным tip main.
  • В detached worktree точного HEAD сопоставлены git-деревья source, merge-base, base и HEAD через git ls-tree -rz. Итоговое дерево точно равно base плюс неизменённый файл плана; пересечения правок и ручного разрешения конфликтов нет. git diff --check c9bbd7540d5f7fd9311ac0017c5d70d2fc1939e9 f948207407a33913891801143901d9ab193f2590 — успешно.
  • go build ./... — успешно.
  • go test -count=1 для 50 пакетов ниже: 48 прошли сразу; в двух пакетах четыре падения классифицированы контрольным прогоном на неизменённом base (подробности ниже). Затем TMPDIR=/tmp go test -count=1 ./internal/dsl/interpreter ./internal/launcher — оба пакета полностью прошли. go vet для всех 50 пакетов — успешно. Список построен по 21 изменённому Go-пакету и транзитивным потребителям, дополнен проверкой нумерации планов; полный go test ./... не запускался.
  • go run ./cmd/onebase check --project examples/trade — ошибок нет. go run ./tools/plannum — 160 планов, номера уникальны; тесты ./tools/plannum включены в целевой прогон.
  • CI точного HEAD: build, lint, postgres-integration, vuln, smoke, e2e, test-windows, launcher-webview-build — SUCCESS; необязательный bench также SUCCESS.

Пакеты для go test -count=1 и go vet:

./cmd/onebase ./internal/access ./internal/aiassist ./internal/aicontext
./internal/api ./internal/app ./internal/auth ./internal/backup
./internal/bench ./internal/cli ./internal/configcheck ./internal/configdb
./internal/converter ./internal/converter/writer ./internal/dbcheck ./internal/dbtest
./internal/dsl/interpreter ./internal/dsl/langref ./internal/dsl/loader ./internal/dslvars
./internal/entityservice ./internal/exchange ./internal/extform ./internal/formdoc
./internal/gengen ./internal/intake ./internal/jobqueue ./internal/launcher
./internal/mailer ./internal/metadata ./internal/onec_forms ./internal/pdfimport
./internal/pipelinecontract ./internal/printform ./internal/processor ./internal/project
./internal/query ./internal/report/expreval ./internal/runtime ./internal/scheduler
./internal/search ./internal/storage ./internal/typedempty ./internal/ui
./internal/widget ./internal/xlsximport ./internal/xlsxtemplate ./tools/pipelinehealth
./tools/releasecheck ./tools/plannum

Классификация первоначальных локальных падений: на base f9de312 в отдельном detached worktree и той же среде повторены:

go test -count=1 ./internal/dsl/interpreter -run '^(TestTempFileNameRejectsPathSyntaxAndUsesRandomToken|TestDSL_ВременныйФайл_ИмяУникальноИЛежитВКаталоге)$'
go test -count=1 ./internal/launcher -run '^(TestUpdatesApply_SharedInstallExplainsLocationNotPermissions|TestUpdatesRollback_SharedInstallDoesNotBlamePolicy)$'

Оба прогона воспроизвели те же четыре ошибки. В interpreter сравнивается очищенный filepath.Dir с os.TempDir, который в штатном окружении macOS имеет завершающий /. Фикстура launcher создаёт якобы общую установку внутри приватного системного temp-каталога, поэтому проверка приватности разрешает её и обработчики доходят до 409 вместо ожидаемого 403. С TMPDIR=/tmp обе причины исчезли без изменения кода. Эти падения не внесены base-sync.

Блокирующее: нет.

Хвост:

  1. [выброс] Зависимость четырёх тестов от штатного TMPDIR macOS: воспроизведена на неизменённом base и устранена настройкой окружения для локальной проверки; доработка этого plan-PR не требуется.

Вердикт: годится к мержу. Интеграционная проверка успешна; существующее разрешение ship сохраняется.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result publication claimed.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: REVIEW result committed.

@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: MERGE transaction reserved.

@ivanarama
ivanarama merged commit 503fb21 into main Sep 17, 2026
13 checks passed
@ivanarama ivanarama removed the ship Иван одобрил мерж: пастух может вливать label Sep 17, 2026
@ivanarama

Copy link
Copy Markdown
Owner Author

PromptPilot service marker: MERGE cleanup completed.

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

Labels

reviewed Ревью: блокирующего нет — ждёт ship

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant