Files
houseplan-card/.github/workflows/process-reconcile.yml
T
Codexandclaude[bot] b35551884f Сторонние Actions закреплены SHA, права выданы по job, граница проверяется фикстурами
Три вещи, которые аудит 12.09 назвал в §10.

**Перемещаемые ссылки.** `home-assistant/actions/hassfest@master` и
`hacs/action@main` — это произвольный будущий коммит чужой ветки, а ревьюера с
Read/Write/Bash запускал перемещаемый major `anthropics/claude-code-action@v1`.
Все 116 `uses:` в девяти воркфлоу закреплены полным SHA с комментарием-версией;
`scripts/action-pins.mjs` это проверяет, а предполётный вердикт Validate —
исполняет. Локальная переиспользуемая workflow пина не требует и исключена
явно.

**Права.** Один блок `permissions` на весь конвейер выдавал `issues: write` и
OIDC каждой стадии, включая единственную недоверенную — работу модели. Теперь
права выдаются по job: модели только чтение и OIDC для самой
`claude-code-action`, писать в issue умеют детерминированные стадии.

**Граница.** Разбор запечатанного результата переехал из inline-shell в
`scripts/review-result-gate.mjs` — не ради красоты, а потому что в YAML его
нельзя прогнать ни одним отрицательным случаем. Проверяются те же вещи, что и
раньше, и в том же объёме: точный набор файлов, контрольные суммы, схема
паспорта и совпадение КАЖДОГО из семнадцати полей с тем, что посчитала
детерминированная стадия. Сверху — пятнадцать враждебных фикстур: неполный
набор, лишний файл, подменённое содержимое, чужой run и попытка, устаревший
material_sha и tree, чужие задача, этап, раунд и ветка, вердикт вне словаря,
пустой документ, manifest не о тех файлах, неразбираемый JSON.

Настоящих секретов и привилегированных операций фикстуры не трогают.

Issue: #556
User-Visible: no
2026-09-13 16:24:10 +00:00

59 lines
2.1 KiB
YAML

name: Сверка очереди ревью
run-name: "reconcile process queue · ${{ github.event_name }}"
on:
schedule:
- cron: '7,37 * * * *'
workflow_dispatch:
inputs:
apply:
description: "Повторно будить потерянные запросы и публиковать диагностику"
required: true
type: boolean
default: true
permissions:
actions: read
contents: read
issues: read
jobs:
reconcile:
name: "Один снимок S4/S7 без polling модели"
runs-on: ubuntu-latest
timeout-minutes: 10
concurrency:
group: process-reconcile
cancel-in-progress: false
steps:
# Расписание читается из main, а исполняемый reconciler — из dev: так
# после штатного merge действует та же версия кода, которую проверил CI.
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: dev
fetch-depth: 1
persist-credentials: false
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: 22
- name: Сопоставить labels, requests, runs и sealed evidence
env:
GH_TOKEN: ${{ secrets.HP_PROCESS_TOKEN }}
REPO: ${{ github.repository }}
APPLY: ${{ github.event_name == 'schedule' || inputs.apply == true }}
run: |
mkdir -p artifacts/process-reconcile
node scripts/process-reconcile.mjs \
--repo "$REPO" \
--apply="$APPLY" \
--max-actions=5 \
--output=artifacts/process-reconcile/summary.json
- name: Опубликовать компактный machine-readable итог
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: process-reconcile-${{ github.run_id }}-${{ github.run_attempt }}
path: artifacts/process-reconcile/summary.json
if-no-files-found: error
retention-days: 14