chore: актуализация проекта — приёмка, задания и история релизов в документации #65
20 changed files with 1530 additions and 1 deletions
206
CHANGELOG.md
206
CHANGELOG.md
|
|
@ -7,8 +7,198 @@ Versions follow the tags in this repository.
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Link management and a real-time Event Journal in the Control web console (#63)
|
||||
|
||||
### Changed
|
||||
- Task, report, and acceptance workflow for agents moved into `agents/` (#64)
|
||||
- `actions/download-artifact` pinned to v8.0.1 across all workflows (#46)
|
||||
- `docker/setup-qemu-action` pinned to v4.2.0 (#44)
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.20] — 2026-08-18
|
||||
|
||||
Published. Carries the work that `v0.1.0-alpha.19` failed to publish.
|
||||
|
||||
### Added
|
||||
- Release pipeline now tests the latest published release before cutting a new
|
||||
one (#62)
|
||||
- Operator web console for nodes, links, and enrollment code generation (#59)
|
||||
- Guided unified installer (#58)
|
||||
- Complete server uninstall mode (#60)
|
||||
- Testing-only password login for the web console (#61)
|
||||
- Node enrollment endpoint (#53)
|
||||
- Desktop update proof (#55)
|
||||
|
||||
### Fixed
|
||||
- Mesh state directory permissions created before Control starts (#57)
|
||||
- `DEFAULT_RELEASE_TAG` in the packaged convenience installer matches the tag
|
||||
being produced — the defect that burned `v0.1.0-alpha.19`
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.19] — 2026-08-18 — burned, not published
|
||||
|
||||
The tag exists, but the Release pipeline failed before a GitHub Release was
|
||||
published: the packaged convenience installer's `DEFAULT_RELEASE_TAG` did not
|
||||
match the immutable tag. The version number is burned and must not be moved,
|
||||
deleted, recreated, or reused. Its content was published under
|
||||
`v0.1.0-alpha.20`.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.18] — 2026-08-18
|
||||
|
||||
### Fixed
|
||||
- Wrong-identity negative test selects cosign v3 explicit detached-output mode,
|
||||
matching the production consumer's detached signature and certificate
|
||||
contract (#56)
|
||||
|
||||
First release required to complete both automatic `workflow_run` verification
|
||||
and manual `workflow_dispatch` re-verification.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.17] — 2026-08-18
|
||||
|
||||
### Fixed
|
||||
- Checksum verification stays fail-closed while its success line is suppressed,
|
||||
so pass-through commands such as `node-code` return only machine-readable
|
||||
bootstrap output (#54)
|
||||
|
||||
Automatic verification completed clean-host Hub and Node installation, then the
|
||||
negative-test harness stopped while creating a wrong-identity signature:
|
||||
cosign v3 requires an explicit bundle or legacy detached-output mode.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.16] — 2026-08-17
|
||||
|
||||
### Fixed
|
||||
- Acceptance shell clears its command hash after removing test-provisioned
|
||||
cosign (#52)
|
||||
|
||||
Automatic verification proved clean-host Hub installation, then failed on the
|
||||
Node: the convenience installer wrote the checksum success line to stdout ahead
|
||||
of the machine-readable `SMMNODE2` enrollment code, so the value was rejected.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.15] — 2026-08-17
|
||||
|
||||
### Added
|
||||
- Pinned, checksum-verified cosign binary provisioned by the installer (#43)
|
||||
|
||||
First release that provisions cosign. Its verification proved clean-host Hub
|
||||
installation and manifest verification, then stopped before the clean-host Node
|
||||
installation: the acceptance script retained the deliberately removed cosign
|
||||
path in Bash's command hash.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.14] — 2026-08-15
|
||||
|
||||
### Fixed
|
||||
- Release signing consistency between producer and consumer (#41, #42)
|
||||
|
||||
First release with the complete manifest, keyless signature, and Fulcio
|
||||
certificate set, so its published assets can be verified. A clean host cannot
|
||||
install it because the release does not provision cosign — preserve it for
|
||||
verification and historical evidence, do not use it for installation.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.13] — 2026-08-13
|
||||
|
||||
### Fixed
|
||||
- Windows checksum asset normalized to LF so GNU `sha256sum -c` can consume it
|
||||
(#39)
|
||||
|
||||
Published with a keyless manifest signature but without the Fulcio signing
|
||||
certificate required by production consumers. The immutable release remains
|
||||
published as historical evidence.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.12] — 2026-08-13
|
||||
|
||||
### Fixed
|
||||
- Network-dependent alpha.8 compatibility test replaced in release
|
||||
verification (#38)
|
||||
|
||||
Published with a keyless manifest signature but without the Fulcio signing
|
||||
certificate, so consumers cannot verify that signature. Its Windows
|
||||
`SHA256SUMS` asset also used CRLF and was not consumable by GNU
|
||||
`sha256sum -c`. Neither defect is repaired in place.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.11] — 2026-08-12 — burned, not published
|
||||
|
||||
The tag exists, but the Release pipeline failed before a GitHub Release was
|
||||
published. The version number is burned and must not be moved, deleted,
|
||||
recreated, or reused.
|
||||
|
||||
Content carried by the tag: release contract updated to alpha.10, backward
|
||||
compatibility test removed from the bootstrap job, Debian VM reboot constraint
|
||||
documented, translations and roadmap synchronized.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.10] — 2026-08-11 — burned, not published
|
||||
|
||||
The tag exists, but the Release pipeline failed before a GitHub Release was
|
||||
published. The version number is burned and must not be moved, deleted,
|
||||
recreated, or reused.
|
||||
|
||||
Content carried by the tag: signed delivery queue B (#35), version comparison
|
||||
fix (#36).
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.9] — 2026-08-10
|
||||
|
||||
### Added
|
||||
- Monitor snapshot contract (#32)
|
||||
|
||||
### Changed
|
||||
- Single-writer release pipeline: `linux-release.yml` is the sole GitHub
|
||||
Release publisher (#33)
|
||||
|
||||
`smm-setup.sh`, its checksum, the bootstrap script, platform archives, SBOMs,
|
||||
and the signed manifest are reproducible from the tagged tree. The installer
|
||||
fetches only same-tag assets and verifies the bootstrap checksum before
|
||||
execution.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.8] — 2026-08-10
|
||||
|
||||
### Added
|
||||
- Source-scoped monitor role (#29)
|
||||
- Certificate lifecycle management
|
||||
- Signed delivery, queue A
|
||||
- Reproducible builds (#15)
|
||||
- Product horizons and KAgent integration specifications (#13)
|
||||
|
||||
### Fixed
|
||||
- CycloneDX SBOM generation in release jobs (#28)
|
||||
- Repository hygiene (#14)
|
||||
|
||||
Contains the v1 `server-monitor-manager-bootstrap-manifest.json` layout and an
|
||||
orphaned `server-monitor-manager-manifest.sig` without the corresponding
|
||||
manifest v2. Published assets remain immutable; the anomaly is documented
|
||||
rather than repaired in place.
|
||||
|
||||
---
|
||||
|
||||
## [v0.1.0-alpha.7] — 2026-08-09
|
||||
|
||||
### Added
|
||||
- Background link reconciliation service for the Control plane (#12)
|
||||
- Link reconciliation driven by factual state (#16)
|
||||
- Provisioning helper coverage for a missing node row (#17)
|
||||
|
||||
### Changed
|
||||
- Link policy reconciliation now runs continuously (#11)
|
||||
|
|
@ -90,7 +280,21 @@ Versions follow the tags in this repository.
|
|||
- Secure node enrollment documentation
|
||||
- Windows build verification in CI
|
||||
|
||||
[Unreleased]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.6...HEAD
|
||||
[Unreleased]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.20...HEAD
|
||||
[v0.1.0-alpha.20]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.19...v0.1.0-alpha.20
|
||||
[v0.1.0-alpha.19]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.18...v0.1.0-alpha.19
|
||||
[v0.1.0-alpha.18]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.17...v0.1.0-alpha.18
|
||||
[v0.1.0-alpha.17]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.16...v0.1.0-alpha.17
|
||||
[v0.1.0-alpha.16]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.15...v0.1.0-alpha.16
|
||||
[v0.1.0-alpha.15]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.14...v0.1.0-alpha.15
|
||||
[v0.1.0-alpha.14]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.13...v0.1.0-alpha.14
|
||||
[v0.1.0-alpha.13]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.12...v0.1.0-alpha.13
|
||||
[v0.1.0-alpha.12]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.11...v0.1.0-alpha.12
|
||||
[v0.1.0-alpha.11]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.10...v0.1.0-alpha.11
|
||||
[v0.1.0-alpha.10]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.9...v0.1.0-alpha.10
|
||||
[v0.1.0-alpha.9]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.8...v0.1.0-alpha.9
|
||||
[v0.1.0-alpha.8]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.7...v0.1.0-alpha.8
|
||||
[v0.1.0-alpha.7]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.6...v0.1.0-alpha.7
|
||||
[v0.1.0-alpha.6]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.5...v0.1.0-alpha.6
|
||||
[v0.1.0-alpha.5]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.4...v0.1.0-alpha.5
|
||||
[v0.1.0-alpha.4]: https://github.com/ochenstarik-ui/server-monitor-manager/compare/v0.1.0-alpha.3...v0.1.0-alpha.4
|
||||
|
|
|
|||
44
agents/_accepted/2026-08-19-console-links/ACCEPTANCE.md
Normal file
44
agents/_accepted/2026-08-19-console-links/ACCEPTANCE.md
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
# Приёмка: управление Links и журнал событий в веб-консоли
|
||||
|
||||
- **Исполнитель:** `antigravity`
|
||||
- **Принял:** `claude` (главный агент)
|
||||
- **Дата приёмки:** 2026-08-19
|
||||
- **PR:** #63, слит коммитом `6115ed0` в `main`
|
||||
|
||||
## Состав пары
|
||||
|
||||
| Файл | Что это |
|
||||
|------|---------|
|
||||
| `task.md` | задание, было `agents/antigravity/inbox/from-smm-deliverables/smm-antigravity-task-console-links-2026-08-18.md` |
|
||||
| `review-by-claude.md` | разбор главного агента, был `agents/claude/done/2026-08-18-review-pr63-console-links.md` |
|
||||
|
||||
Отдельного файла отчёта исполнителя нет: отчёт оформлен разделом в описании
|
||||
PR #63, как принято в проекте.
|
||||
|
||||
## Основание приёмки
|
||||
|
||||
Диф снят от базы слияния `7c43977`. Границы задания соблюдены: 4 файла,
|
||||
`deploy/**`, релизные workflow и bootstrap-тесты не затронуты, новых
|
||||
эндпоинтов Control нет. Дефектов безопасности не найдено: экранирование в
|
||||
консоли сплошное, разбор NDJSON держит границу чанка, журнал ограничен,
|
||||
переподключение не размножает таймеры. Подробности — в `review-by-claude.md`.
|
||||
|
||||
Перед слиянием ветка обновлена относительно `main` (коммит `2459660`),
|
||||
проверки `build` и `build-and-test` пройдены на обновлённой базе.
|
||||
|
||||
## Принято с открытыми замечаниями
|
||||
|
||||
Два замечания разбора в код не вносились и слияние не блокировали. По ним
|
||||
выпущены отдельные задания:
|
||||
|
||||
- `agents/antigravity/inbox/2026-08-19-console-behaviour-tests.md` —
|
||||
тесты проверяют строки в статическом HTML, а не поведение;
|
||||
- `agents/antigravity/inbox/2026-08-19-console-events-throttle.md` —
|
||||
обновление дашборда по событиям не троттлится.
|
||||
|
||||
## Чего приёмка не доказывает
|
||||
|
||||
`dotnet build` и `dotnet test` главным агентом не запускались: на машине
|
||||
приёмки нет .NET SDK. Заявленные исполнителем 158 пройденных тестов и
|
||||
зелёные прогоны CI приняты по ссылкам на прогоны. Консоль в браузере не
|
||||
открывалась, поведение вручную не проверялось.
|
||||
116
agents/_accepted/2026-08-19-console-links/review-by-claude.md
Normal file
116
agents/_accepted/2026-08-19-console-links/review-by-claude.md
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# Отчёт: разбор PR #63 «Link management и Event Journal в веб-консоли»
|
||||
|
||||
- **Задание:** роль главного агента, подтверждена владельцем в чате 2026-08-18
|
||||
- **Агент:** `claude` (в роли главного агента)
|
||||
- **Дата:** 2026-08-18
|
||||
- **Разбираемая работа:** PR #63, ветка `antigravity/console-links`,
|
||||
коммит `051d917`; задание —
|
||||
`agents/antigravity/inbox/from-smm-deliverables/smm-antigravity-task-console-links-2026-08-18.md`;
|
||||
отчёт исполнителя — описание PR #63.
|
||||
|
||||
## Что сделано
|
||||
|
||||
Разбор по репозиторию, а не по отчёту: диф снят от базы слияния
|
||||
`7c43977`, а не от `main`.
|
||||
|
||||
## Как проверено
|
||||
|
||||
```
|
||||
$ git merge-base origin/main origin/antigravity/console-links
|
||||
7c43977fd137c2236f7fc100f5d972f4e5f2bcac
|
||||
|
||||
$ git diff --stat 7c43977 origin/antigravity/console-links
|
||||
src/ServerMonitorManager.Control/wwwroot/app.js | 722 +++++++++++++++++----
|
||||
src/ServerMonitorManager.Control/wwwroot/index.html| 179 ++++-
|
||||
src/ServerMonitorManager.Control/wwwroot/style.css | 156 ++++-
|
||||
tests/.../WebConsoleTests.cs | 45 +-
|
||||
4 files changed, 976 insertions(+), 126 deletions(-)
|
||||
```
|
||||
|
||||
Границы задания соблюдены: `deploy/**`, релизные workflow и bootstrap-тесты
|
||||
не затронуты, новых эндпоинтов нет. Заявленный в описании PR состав файлов
|
||||
совпадает с фактическим.
|
||||
|
||||
**Проверено и подтверждается:**
|
||||
|
||||
- **XSS не найден.** `escapeHtml` (app.js:1045) экранирует пять сущностей
|
||||
(`& < > " '`) и применён при каждой интерполяции в `innerHTML`, включая
|
||||
payload событий (app.js:479), `lastError` (338) и `data-*`-атрибуты
|
||||
(347–351). Непроэкранированных вставок пользовательских данных не найдено.
|
||||
- **Разбор NDJSON корректен.** app.js:412–413 — `split('\n')` с
|
||||
возвратом хвоста в буфер через `pop()`; разрыв события на границе чанка
|
||||
не теряется и не портит разбор.
|
||||
- **Переподключение не размножается.** `startEventStream` вызывается ровно
|
||||
из двух мест (app.js:89 при инициализации и 431 по таймеру), в начале
|
||||
функции прежний `AbortController` прерывается. Накопления параллельных
|
||||
таймеров нет.
|
||||
- **Журнал ограничен**: `MAX_EVENTS_IN_JOURNAL = 100`, `unshift` + `pop`
|
||||
(app.js:437–439). Неограниченного роста в долгоживущей вкладке нет.
|
||||
|
||||
## Замечания
|
||||
|
||||
**1. Тесты не проверяют поведение — только строки в статическом HTML.**
|
||||
|
||||
Оба теста (`WebConsoleHtmlContainsRequiredUiElementsAndWarning` и новый
|
||||
`WebConsoleProvidesLinkManagementAndEventsJournal`) состоят из
|
||||
`Assert.Contains("id=\"…\"", html)` по разметке. Они доказывают, что в
|
||||
`index.html` есть элементы с нужными идентификаторами, и ничего больше.
|
||||
|
||||
При этом 976 изменённых строк — почти целиком поведение на JavaScript:
|
||||
создание Link, отключение, идемпотентность, разбор потока событий,
|
||||
расчёт срока действия, разбор Problem Details. Ни одна из этих веток
|
||||
тестом не покрыта.
|
||||
|
||||
В описании PR «158 пройденных тестов» приведено как доказательство работы
|
||||
управления Links. Это не доказательство: пройдёт и разметка с правильными
|
||||
`id` при полностью нерабочем `app.js`. Соглашение 6 из
|
||||
`agents/claude/notes/2026-08-18-передача-состояния.md` — «зелёный CI не
|
||||
означает работающую машину» — здесь применимо буквально.
|
||||
|
||||
**2. Обновление дашборда не троттлится (app.js:444–448).**
|
||||
|
||||
```js
|
||||
const eventType = (ev.type || '').toLowerCase();
|
||||
if (eventType.startsWith('link.') || eventType.startsWith('agent.')) {
|
||||
loadDashboardData(false);
|
||||
}
|
||||
```
|
||||
|
||||
Каждое событие `link.*` или `agent.*` вызывает `loadDashboardData`, а тот
|
||||
делает два запроса — `/api/v1/control/agents` и `/api/v1/control/links`
|
||||
(app.js:230–233). Ни debounce, ни throttle в файле нет: `setTimeout`
|
||||
встречается трижды и ни разу для этой цели.
|
||||
|
||||
Согласование политик Links в Control работает непрерывно (`CHANGELOG.md`,
|
||||
Unreleased, #11). Пачка событий согласования по флоту превращается в
|
||||
двукратно умноженный поток запросов от каждой открытой вкладки консоли.
|
||||
На одном узле незаметно, на флоте — усилитель нагрузки на Control.
|
||||
|
||||
**3. Мелкое: запасной `generateUuid` на `Math.random()` (app.js:167).**
|
||||
|
||||
Для ключа идемпотентности приемлемо — это не секрет. Отмечаю только чтобы
|
||||
запасная ветка не была скопирована туда, где нужна криптостойкость.
|
||||
|
||||
## Что не сделано
|
||||
|
||||
- `dotnet build` и `dotnet test` не запускались: на машине нет .NET SDK
|
||||
(`dotnet: command not found` и в Git Bash, и в PowerShell). Заявленные
|
||||
в описании PR 158 пройденных тестов и зелёные прогоны CI я принимаю по
|
||||
ссылкам на прогоны, а не по собственному запуску;
|
||||
- консоль в браузере не открывалась, поведение вручную не проверялось;
|
||||
- PR не слит: ветка отстала от `main` (`mergeStateStatus = BEHIND`),
|
||||
и решение о слиянии за владельцем.
|
||||
|
||||
## Решение
|
||||
|
||||
Работа соответствует заданию по составу и границам, дефектов безопасности
|
||||
в ней не найдено. К слиянию пригодна после обновления относительно `main`.
|
||||
|
||||
Замечание 1 не блокирует слияние, но должно стать отдельным заданием: без
|
||||
поведенческих тестов следующая правка `app.js` не будет ничем удержана.
|
||||
Замечание 2 — отдельным заданием на исправление.
|
||||
|
||||
## Вопросы к приёмке
|
||||
|
||||
- Обновлять ветку относительно `main` силами `claude` или возвращать автору?
|
||||
- Выпускать ли задания по замечаниям 1 и 2 сразу, или после слияния #63.
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
# Поведенческие тесты веб-консоли
|
||||
|
||||
- **Кому:** `antigravity`
|
||||
- **Дата:** 2026-08-19
|
||||
- **От кого:** главный агент (`claude`), по разбору PR #63 —
|
||||
`agents/claude/done/2026-08-18-review-pr63-console-links.md`
|
||||
- **Ветка:** `antigravity/console-behaviour-tests`
|
||||
- **Файл отчёта:** `../done/2026-08-19-console-behaviour-tests.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Покрыть тестами поведение веб-консоли, а не наличие разметки.
|
||||
|
||||
Сейчас `tests/ServerMonitorManager.Control.Tests/WebConsoleTests.cs` состоит
|
||||
из проверок вида `Assert.Contains("id=\"create-link-btn\"", html)`. Такие
|
||||
тесты проходят и при полностью нерабочем `app.js`: они доказывают, что в
|
||||
`index.html` есть элемент с нужным идентификатором, и ничего больше. При этом
|
||||
в PR #63 977 строк изменений — почти целиком логика на JavaScript.
|
||||
|
||||
Нужны тесты, падающие при поломке поведения. Как минимум:
|
||||
|
||||
1. **Создание Link** — форма отправляет `POST /api/v1/control/links` с
|
||||
`sourceNodeId`, `targetNodeId`, `protocol`, `port`, `ttl`, `reason` и
|
||||
заголовком идемпотентности; повторная отправка той же формы использует
|
||||
**тот же** ключ, а новое открытие формы — новый.
|
||||
2. **Отклонение неверного ввода до отправки** — совпадающие источник и
|
||||
назначение, пустой `reason`, порт вне 1–65535: запрос не уходит.
|
||||
3. **Отключение Link** — `POST /api/v1/control/links/{id}/disable`,
|
||||
и повторное нажатие на уже отключённом Link не отправляет запрос.
|
||||
4. **Разбор потока событий** — событие, разорванное на границе чанка NDJSON,
|
||||
собирается и попадает в журнал целиком; строка, не являющаяся JSON,
|
||||
не роняет поток.
|
||||
5. **Ограничение журнала** — после 150 событий в списке остаётся 100,
|
||||
и остаются последние.
|
||||
6. **Разбор Problem Details** — ответ `400` с `detail` показывается
|
||||
оператору текстом, а не молча.
|
||||
|
||||
Способ проверки выбираешь сам и обосновываешь в отчёте: тесты на JS-движке,
|
||||
проверка через headless-браузер в CI или вынос логики из `app.js` в
|
||||
тестируемый модуль. Требование одно: тест должен падать, когда поведение
|
||||
сломано. Если для этого нужна новая зависимость или шаг в CI — предложи в
|
||||
отчёте, не добавляй молча.
|
||||
|
||||
## Замечено при показе консоли
|
||||
|
||||
Мелкий дефект текста, найденный при прогоне консоли на стенде. Исправить
|
||||
здесь же, отдельного задания он не стоит.
|
||||
|
||||
Строка подтверждения направления заканчивается двумя точками:
|
||||
|
||||
```
|
||||
Открытие доступа: с узла «demo-hub» к узлу «demo-home», протокол TCP, порт 443, на 60 мин..
|
||||
```
|
||||
|
||||
Сокращение «мин.» уже содержит точку, и к нему добавляется точка
|
||||
предложения. Тест из пункта 1 должен проверять эту строку целиком, тогда
|
||||
дефект и не вернётся.
|
||||
|
||||
## Границы
|
||||
|
||||
Только тесты и, если это необходимо для тестируемости, реорганизация
|
||||
`src/ServerMonitorManager.Control/wwwroot/app.js` без изменения поведения.
|
||||
Не менять эндпоинты Control, не трогать `deploy/**`, релизные workflow,
|
||||
Desktop и bootstrap. Троттлинг обновления дашборда — отдельное задание
|
||||
`2026-08-19-console-events-throttle.md`, здесь его не делать.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- каждый новый тест предъявить дважды: зелёным на исправном коде и **красным**
|
||||
на намеренно сломанном поведении. В отчёт — вывод обоих прогонов. Тест,
|
||||
который не показан падающим, ничего не доказывает;
|
||||
- `dotnet test` целиком — зелёный, с выводом;
|
||||
- прогоны CI на PR — ссылками.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Соглашение 6 из `agents/claude/notes/2026-08-18-передача-состояния.md`:
|
||||
зелёный CI не означает работающую машину. Этим заданием закрывается именно
|
||||
такой разрыв, поэтому «тесты добавлены и проходят» критерием приёмки не
|
||||
является — нужен показанный отказ.
|
||||
|
||||
Формат отчёта — раздел в описании PR плюс файл в `done/`.
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
# Троттлинг обновления дашборда по событиям
|
||||
|
||||
- **Кому:** `antigravity`
|
||||
- **Дата:** 2026-08-19
|
||||
- **От кого:** главный агент (`claude`), по разбору PR #63 —
|
||||
`agents/claude/done/2026-08-18-review-pr63-console-links.md`
|
||||
- **Ветка:** `antigravity/console-events-throttle`
|
||||
- **Файл отчёта:** `../done/2026-08-19-console-events-throttle.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Убрать усиление нагрузки на Control при пачке событий.
|
||||
|
||||
В `src/ServerMonitorManager.Control/wwwroot/app.js` обработчик события
|
||||
делает так:
|
||||
|
||||
```js
|
||||
const eventType = (ev.type || '').toLowerCase();
|
||||
if (eventType.startsWith('link.') || eventType.startsWith('agent.')) {
|
||||
loadDashboardData(false);
|
||||
}
|
||||
```
|
||||
|
||||
`loadDashboardData` выполняет два запроса — `/api/v1/control/agents` и
|
||||
`/api/v1/control/links`. Ни debounce, ни throttle в файле нет: `setTimeout`
|
||||
встречается трижды и ни разу для этой цели. Согласование политик Links в
|
||||
Control работает непрерывно (`CHANGELOG.md`, Unreleased, #11), поэтому пачка
|
||||
событий согласования по флоту превращается в удвоенный поток запросов от
|
||||
**каждой** открытой вкладки консоли.
|
||||
|
||||
Нужно свести пачку событий к одному обновлению. Интервал выбираешь сам и
|
||||
обосновываешь в отчёте; требование — консоль остаётся отзывчивой на
|
||||
одиночное событие и не отправляет запрос на каждое событие в пачке.
|
||||
Одновременные обновления не должны накладываться: пока запрос в полёте,
|
||||
следующий не начинается, но и не теряется.
|
||||
|
||||
## Границы
|
||||
|
||||
Только `app.js`. Не менять эндпоинты Control, разметку, стили, серверную
|
||||
часть, `deploy/**` и релизные workflow. Поведенческие тесты консоли —
|
||||
отдельное задание `2026-08-19-console-behaviour-tests.md`.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- предъявить количество запросов на пачке событий до и после правки:
|
||||
на N событий подряд должно уйти одно обновление, а не N. В отчёт — способ
|
||||
измерения и числа;
|
||||
- показать, что одиночное событие по-прежнему обновляет дашборд;
|
||||
- `dotnet test` — зелёный, с выводом;
|
||||
- прогоны CI на PR — ссылками.
|
||||
|
||||
«Стало лучше» без чисел результатом проверки не является.
|
||||
|
||||
## Измерение, уже проведённое
|
||||
|
||||
Дефект найден чтением кода, но затем воспроизведён и измерен на стенде:
|
||||
настоящие файлы консоли из `wwwroot` под локальным макетом Control API.
|
||||
Числа получены из журнала сетевых запросов браузера.
|
||||
|
||||
- **Установившийся режим.** Одно событие → одно `loadDashboardData` → два
|
||||
запроса (`/agents` и `/links`). Слияния соседних событий нет ни одного.
|
||||
- **Пачка при подключении.** Поток отдал 15 накопленных событий разом —
|
||||
консоль выпустила 22 обновления дашборда, то есть **44 запроса примерно
|
||||
за 0,1 секунды**. Это одна вкладка и четыре узла.
|
||||
- **Побочный эффект.** Каждое обновление перестраивает `innerHTML` таблицы
|
||||
Links целиком. Во время пачки ссылки на элементы строки становятся
|
||||
недействительными, и таблица перестраивается под курсором оператора.
|
||||
|
||||
Воспроизведение: открыть консоль под макетом Control, отдающим backlog
|
||||
событий при подключении к `/api/v1/control/events`, и посмотреть журнал
|
||||
сетевых запросов.
|
||||
|
||||
Отсюда следует уточнение к проверке: измерять надо именно пачку, а не
|
||||
установившийся режим — в установившемся режиме при одном событии в 6 секунд
|
||||
разница незаметна.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Измерение сделано на макете API, а не на живом Hub: скорость поступления
|
||||
событий на настоящем флоте не проверена. Если на живой машине окажется, что
|
||||
пачек не бывает и усиления нет, — так и напиши в отчёте с числами; это
|
||||
допустимый результат, а не провал задания.
|
||||
110
agents/antigravity/inbox/2026-08-20-console-node-metrics.md
Normal file
110
agents/antigravity/inbox/2026-08-20-console-node-metrics.md
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
# Метрики и короткая история узлов в веб-консоли
|
||||
|
||||
- **Кому:** `antigravity`
|
||||
- **Дата:** 2026-08-20
|
||||
- **От кого:** главный агент (`claude`), по задаче владельца «консоль надо
|
||||
сделать так же, как и Windows-программа»
|
||||
- **Ветка:** `antigravity/console-node-metrics`
|
||||
- **Файл отчёта:** `../done/2026-08-20-console-node-metrics.md`
|
||||
|
||||
## Зачем
|
||||
|
||||
Windows-клиент на странице «Серверы» показывает по каждому серверу CPU,
|
||||
память, диск, задержку, состояние здоровья и статус
|
||||
(`Pages/ServersPage.xaml`: `CpuText`, `MemoryText`, `DiskText`,
|
||||
`LatencyText`, `HealthText`, `Status`). Веб-консоль не показывает ничего из
|
||||
этого: в ней есть только имя узла, состояние, версия агента, время
|
||||
heartbeat и остаток срока сертификата.
|
||||
|
||||
Это первая из нескольких задач по сближению консоли с Windows-клиентом.
|
||||
Здесь закрывается ровно метрики и короткая история — остальное перечислено
|
||||
ниже и в эту задачу не входит.
|
||||
|
||||
## Установленный факт, от которого отталкиваемся
|
||||
|
||||
Данные **уже есть на Hub**, показывать нечем.
|
||||
|
||||
`ControlStore` содержит таблицу (`ControlStore.cs:81`):
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS metric_samples (
|
||||
sequence INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
node_id TEXT NOT NULL REFERENCES agents(node_id) ON DELETE CASCADE,
|
||||
recorded_at TEXT NOT NULL,
|
||||
payload_json TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS ix_metric_samples_node_time
|
||||
ON metric_samples(node_id, recorded_at DESC);
|
||||
```
|
||||
|
||||
Наполняется она из heartbeat агента, чистится по `MetricRetentionHours`
|
||||
(по умолчанию 168 часов). При этом в группе `/api/v1/control` **нет ни
|
||||
одного маршрута для метрик** — я перечитал все `control.Map*` в
|
||||
`Program.cs`. То есть оператор физически не может их получить.
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
1. **Добавить в Control чтение метрик под ролью Operator.** Как минимум
|
||||
последний срез по каждому узлу и история по одному узлу за period.
|
||||
Форму запроса, имена полей и ограничение на объём выбираешь сам и
|
||||
обосновываешь в отчёте. Обязательные требования: маршрут в группе
|
||||
`control` (то есть `RequireAuthorization("Operator")`), ограничение
|
||||
количества возвращаемых точек, и никакого доступа к чужим данным по
|
||||
роли Agent или Automation.
|
||||
2. **Показать это в консоли** в разделе узлов: текущие CPU, память, диск и
|
||||
задержка рядом с узлом, плюс короткая история — так же, как её
|
||||
показывает Windows-клиент.
|
||||
3. **`payload_json` — данные из внешнего источника.** Он приходит от
|
||||
агента. Разбирать его в консоли только через уже имеющийся
|
||||
`escapeHtml`, как это сделано с payload событий; ни одной вставки в
|
||||
`innerHTML` без экранирования. Отсутствующие или битые поля не должны
|
||||
ронять таблицу узлов.
|
||||
|
||||
## Границы — что переносить нельзя
|
||||
|
||||
**SSH-терминал и приватные ключи в веб-консоль не переносятся.** Это не
|
||||
вопрос трудоёмкости, а заявленное свойство продукта: README обещает
|
||||
«opens direct SSH terminals without sending a private terminal key to the
|
||||
Hub», а ключ мониторинга и сертификат оператора защищены DPAPI и лежат
|
||||
только на Windows-машине. Страница Sessions остаётся у Windows-клиента.
|
||||
|
||||
Также не входит в эту задачу и делается отдельно: страница Settings,
|
||||
группы и теги серверов, alert rules и журнал уведомлений (последние два
|
||||
пункта в `docs/roadmap.md` числятся невыполненными и для Windows-клиента).
|
||||
|
||||
Не трогать: `deploy/**`, релизные workflow, Desktop, схему существующих
|
||||
таблиц (добавление индексов допустимо и обосновывается).
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- новый маршрут закрыт ролью: запрос без токена → 401, под ролью Agent и
|
||||
Automation → 403, под Operator → 200. Три теста, вывод в отчёт;
|
||||
- ограничение объёма истории проверено тестом: запрос заведомо большего
|
||||
количества точек возвращает не больше предела;
|
||||
- битый или неполный `payload_json` не роняет ни маршрут, ни отрисовку —
|
||||
тест на каждую сторону;
|
||||
- `dotnet test` целиком зелёный, с выводом;
|
||||
- прогоны CI на PR — ссылками.
|
||||
|
||||
## Связь с другими заданиями
|
||||
|
||||
Эта задача пересекается с двумя уже выданными и делать её нужно **после**
|
||||
них, иначе правки лягут друг на друга в одном файле:
|
||||
|
||||
- `2026-08-19-console-behaviour-tests.md` — поведенческие тесты консоли.
|
||||
Новая функциональность обязана прийти с такими тестами сразу, а не
|
||||
проверками строк в HTML;
|
||||
- `2026-08-19-console-events-throttle.md` — троттлинг обновления дашборда.
|
||||
Метрики увеличат объём каждого обновления, поэтому без троттлинга
|
||||
усиление нагрузки станет заметнее.
|
||||
|
||||
Если считаешь, что порядок должен быть другим, — скажи в отчёте и обоснуй,
|
||||
это решение приму.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Проверено чтением кода и запуском Control локально на пустой базе: узлов
|
||||
ноль, метрик ноль. Как выглядят настоящие `payload_json` от живого агента,
|
||||
я не видел — на живом Hub не проверял. Прежде чем фиксировать контракт
|
||||
ответа, посмотри фактическую форму payload в коде агента, а не в моём
|
||||
описании.
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
# Согласование Links дёргает привилегированный процесс каждые 30 секунд
|
||||
|
||||
- **Кому:** `antigravity`
|
||||
- **Дата:** 2026-08-20
|
||||
- **От кого:** главный агент (`claude`)
|
||||
- **Ветка:** `antigravity/reconciliation-poll-interval`
|
||||
- **Файл отчёта:** `../done/2026-08-20-reconciliation-poll-interval.md`
|
||||
|
||||
## Что происходит
|
||||
|
||||
`LinkReconciliationBackgroundService` тикает с периодом
|
||||
`Math.Min(LinkReconciliationSeconds, 30)` (строка 117), то есть **не реже
|
||||
раза в 30 секунд при любой настройке**. На каждом тике первым делом
|
||||
безусловно вызывается `applier.GetReconciliationRequestAsync(...)`
|
||||
(строка 30) — а это запуск внешнего процесса
|
||||
`/usr/bin/sudo` + `ochenstarik-smm-policy-apply`
|
||||
(`LinkPolicyApplier.RunAsync`, строка 143).
|
||||
|
||||
Отсюда два следствия.
|
||||
|
||||
**1. Настройка не ограничивает привилегированные вызовы.**
|
||||
`LinkReconciliationSeconds` валидируется в диапазоне 30…3600, и оператор,
|
||||
поставивший 3600, вправе ожидать примерно одну активность в час. Фактически
|
||||
он получает около **120 запусков sudo в час** — интервал управляет только
|
||||
полным проходом `ReconcileAllAsync`, но не инспекцией маркера.
|
||||
|
||||
**2. Backoff не подавляет эти вызовы.** Проверка `_backoffUntil`
|
||||
(строки 35–38) стоит **после** обращения к маркеру. Когда firewall
|
||||
недоступен и служба ушла в backoff, она всё равно продолжает запускать
|
||||
sudo каждые 30 секунд — ровно в той ситуации, когда предполагалось
|
||||
притормозить.
|
||||
|
||||
Каждая неудачная инспекция пишет предупреждение с полным стеком.
|
||||
|
||||
## Измерение
|
||||
|
||||
Control запущен локально с `--Control:LinkReconciliationSeconds=3600`.
|
||||
Журнал приложений Windows, провайдер `.NET Runtime`, категория
|
||||
`ServerMonitorManager.Control.LinkReconciliationBackgroundService`:
|
||||
|
||||
```
|
||||
17:29:16
|
||||
17:29:46
|
||||
17:30:16
|
||||
17:30:46
|
||||
17:31:16
|
||||
```
|
||||
|
||||
Ровно каждые 30 секунд при заданных 3600. Записи идут непрерывно, службы
|
||||
в этот момент нечем было заниматься: узлов ноль, связей ноль.
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Привести поведение в соответствие с настройкой, **не потеряв быструю
|
||||
реакцию на маркер** — она и есть смысл 30-секундного опроса, её ломать
|
||||
нельзя.
|
||||
|
||||
Как минимум:
|
||||
|
||||
1. Не обращаться к маркеру, пока действует `_backoffUntil`. Сейчас backoff
|
||||
не защищает ни от чего.
|
||||
2. Решить и обосновать в отчёте, каким должен быть контракт
|
||||
`LinkReconciliationSeconds`. Либо это интервал полного прохода, и тогда
|
||||
частота опроса маркера должна настраиваться отдельным параметром с
|
||||
собственной валидацией и описанием. Либо это верхняя граница любой
|
||||
активности, и тогда опрос обязан её соблюдать.
|
||||
3. Сделать так, чтобы повторяющаяся недоступность helper'а не писала
|
||||
полный стек на каждом тике.
|
||||
|
||||
Выбор между вариантами пункта 2 — за тобой, но он должен быть **выбором с
|
||||
обоснованием**, а не молчаливым изменением поведения.
|
||||
|
||||
## Границы
|
||||
|
||||
`src/ServerMonitorManager.Control/LinkReconciliationBackgroundService.cs`,
|
||||
при необходимости `ControlOptions` и валидация в `Program.cs`, плюс тесты
|
||||
`tests/ServerMonitorManager.Control.Tests/LinkReconciliationTests.cs`.
|
||||
Не трогать `LinkService.ReconcileAllAsync`, helper в `deploy/**`, консоль
|
||||
и Desktop.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- `dotnet test tests/ServerMonitorManager.Control.Tests/...` — все 158
|
||||
существующих тестов зелёные, с выводом. Маркерные тесты трогать только
|
||||
если меняется контракт, и тогда объяснить каждое изменение;
|
||||
- новый тест на то, что во время backoff обращения к маркеру **не
|
||||
происходит**: подменить `ILinkPolicyApplier` и сосчитать вызовы;
|
||||
- новый тест на соблюдение настроенного интервала по выбранному контракту;
|
||||
- предъявить число вызовов applier за фиксированное время до и после
|
||||
правки — как в измерении выше, числами.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Дефект найден на живом прогоне Control на Windows, где helper'а нет вовсе,
|
||||
поэтому каждая инспекция падает. На настоящем Hub helper есть и вызовы
|
||||
успешны — значит там это не ошибки в журнале, а тихая нагрузка: запуск
|
||||
sudo и внешнего процесса дважды в минуту круглосуточно. Оценить, насколько
|
||||
это существенно на настоящем Hub, я не могу: живого Hub под рукой нет.
|
||||
Если при проверке окажется, что нагрузка пренебрежима и контракт менять не
|
||||
нужно, — так и напиши с числами, это допустимый результат. Пункт 1 про
|
||||
backoff при этом всё равно остаётся к исправлению.
|
||||
151
agents/claude/done/2026-08-18-deps-update.md
Normal file
151
agents/claude/done/2026-08-18-deps-update.md
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
# Отчёт: обновление зависимостей GitHub Actions и NuGet
|
||||
|
||||
- **Задание:** `../inbox/2026-08-18-deps-update.md`
|
||||
- **Агент:** `claude`
|
||||
- **Дата:** 2026-08-18
|
||||
- **Ветка / коммиты:** `claude/deps-update`. Правок workflow эта ветка не
|
||||
несёт — см. «Как доставлено».
|
||||
|
||||
## Что сделано
|
||||
|
||||
Разобрано отставание зависимостей и проверены три открытых PR Dependabot по
|
||||
GitHub Actions. Проверка была содержательной, а не сводилась к «CI зелёный».
|
||||
|
||||
- `actions/download-artifact` v4.1.8 → v8.0.1 (PR #46). Затрагивает одну
|
||||
точку — `linux-release.yml:256`; это была последняя старая ссылка в дереве,
|
||||
`linux-platform-matrix.yml` уже использовал v8.0.1 (SHA `3e5f45b2…`).
|
||||
Обновление приводит репозиторий к одной версии.
|
||||
- `docker/setup-qemu-action` → v4.2.0 (PR #44). Одна точка,
|
||||
`linux-control-agent.yml:83`; прежняя ссылка была закреплена по SHA
|
||||
`c7c53464…` с комментарием `# v3` без минорной версии.
|
||||
- `sigstore/cosign-installer` v3.5.0 → v4.1.2 (PR #45). **Не принят**,
|
||||
причина в разделе «Вопросы к приёмке».
|
||||
|
||||
Все три правки я предварительно применял локально и построчно сверял с
|
||||
ветками Dependabot — совпадение полное. Затем правки из ветки сняты, чтобы
|
||||
не применить одно и то же дважды: доставка идёт слиянием PR Dependabot.
|
||||
|
||||
NuGet не обновлялся — см. «Что не сделано».
|
||||
|
||||
## Как доставлено
|
||||
|
||||
Решением владельца от 2026-08-18: сливаются PR #44 и #46, правки из этой
|
||||
ветки сняты. В ветке остаются только задания, отчёты и записка передачи
|
||||
состояния. PR #45 остаётся открытым.
|
||||
|
||||
## Как проверено
|
||||
|
||||
Сверка применённых правок с ветками Dependabot (до снятия правок):
|
||||
|
||||
```
|
||||
$ git diff -- .github/ | grep -E '^[+-][^+-]' | sort > mine.lines
|
||||
$ for b in dependabot/github_actions/actions/download-artifact-8.0.1 \
|
||||
dependabot/github_actions/sigstore/cosign-installer-4.1.2 \
|
||||
dependabot/github_actions/docker/setup-qemu-action-4.2.0; do
|
||||
git diff origin/main...origin/$b -- .github/
|
||||
done | grep -E '^[+-][^+-]' | sort > pr.lines
|
||||
$ diff pr.lines mine.lines
|
||||
СОВПАДАЕТ построчно
|
||||
```
|
||||
|
||||
Старых версий после применения в дереве не оставалось:
|
||||
|
||||
```
|
||||
$ grep -rn "download-artifact@fa0a91b8\|cosign-installer@v3\|setup-qemu-action@c7c53464" .github/workflows/
|
||||
старых версий не осталось
|
||||
```
|
||||
|
||||
YAML всех шести workflow разбирается:
|
||||
|
||||
```
|
||||
$ for f in .github/workflows/*.yml; do python -c "import sys,yaml;yaml.safe_load(open(sys.argv[1],encoding='utf-8'));print('OK',sys.argv[1])" "$f"; done
|
||||
OK .github/workflows/linux-control-agent.yml
|
||||
OK .github/workflows/linux-platform-matrix.yml
|
||||
OK .github/workflows/linux-release.yml
|
||||
OK .github/workflows/release-verification.yml
|
||||
OK .github/workflows/windows-build.yml
|
||||
OK .github/workflows/windows-release.yml
|
||||
```
|
||||
|
||||
Текущее состояние ветки — правок workflow нет:
|
||||
|
||||
```
|
||||
$ git diff 23eb3f5 --stat -- .github/
|
||||
(пусто)
|
||||
```
|
||||
|
||||
## Что не сделано
|
||||
|
||||
**NuGet не обновлён — нет .NET SDK на машине.**
|
||||
|
||||
```
|
||||
$ dotnet --version
|
||||
bash: dotnet: command not found
|
||||
|
||||
PS> Get-Command dotnet
|
||||
dotnet not found on PATH
|
||||
```
|
||||
|
||||
В `Directory.Build.props` включён `RestorePackagesWithLockFile=true`, в CI
|
||||
сборка идёт с `-p:RestoreLockedMode=true`, и в дереве семь
|
||||
`packages.lock.json`. Поднять версию в `Directory.Packages.props` без
|
||||
пересборки lock-файлов — гарантированно уронить CI. Без SDK пересобрать их
|
||||
нечем, поэтому файлы не тронуты.
|
||||
|
||||
Отставание по данным `api.nuget.org` на 2026-08-18 (запрошены версии,
|
||||
`dotnet list package --outdated` не запускался):
|
||||
|
||||
| Пакет | В репозитории | Актуальная |
|
||||
|-------|---------------|------------|
|
||||
| Microsoft.AspNetCore.Authentication.Certificate | 10.0.10 | 10.0.11 |
|
||||
| Microsoft.AspNetCore.Mvc.Testing | 10.0.10 | 10.0.11 |
|
||||
| Microsoft.Data.Sqlite | 10.0.10 | 10.0.11 |
|
||||
| Microsoft.Extensions.Configuration.* (4 пакета) | 10.0.10 | 10.0.11 |
|
||||
| System.Security.Cryptography.ProtectedData | 10.0.0 | 10.0.11 |
|
||||
| Microsoft.NET.ILLink.Tasks (`Directory.Build.props`) | 10.0.10 | 10.0.11 |
|
||||
| Microsoft.Windows.SDK.BuildTools | 10.0.28000.2270 | 10.0.28000.2526 |
|
||||
| Microsoft.Windows.SDK.BuildTools.WinApp | 0.4.0 | 0.6.0 |
|
||||
| Microsoft.WindowsAppSDK | 2.2.0 | 2.4.0 |
|
||||
| Microsoft.NET.Test.Sdk | 18.8.1 | 18.9.0 |
|
||||
| xunit.v3 | 3.2.2 | 4.0.0 (мажорная) |
|
||||
| xunit.runner.visualstudio | 3.1.5 | 4.0.0 (мажорная) |
|
||||
| SQLitePCLRaw.bundle_e_sqlite3 | 3.0.5 | 3.0.5 — актуален |
|
||||
|
||||
Открытых PR Dependabot по NuGet нет, хотя в `.github/dependabot.yml`
|
||||
экосистема `nuget` настроена с недельным интервалом. Причина не определена.
|
||||
|
||||
## Замечено рядом
|
||||
|
||||
Вне границ задачи; предлагаю отдельными заданиями.
|
||||
|
||||
1. **`sigstore/cosign-installer` закреплён тегом, а не SHA.** Все остальные
|
||||
действия в репозитории закреплены по коммиту с комментарием версии;
|
||||
cosign-installer — единственное исключение, и это единственное действие,
|
||||
от которого зависит подпись релиза. Тег подвижен.
|
||||
2. **`Microsoft.Windows.SDK.BuildTools.WinApp` 0.4.0** — версия ниже 1.0,
|
||||
мажорных гарантий совместимости нет; переход на 0.6.0 делать отдельно.
|
||||
3. **xunit 3 → 4 — мажорный переход** для двух пакетов, отдельной задачей
|
||||
с прогоном тестов.
|
||||
|
||||
## Вопросы к приёмке
|
||||
|
||||
**PR #45 (`cosign-installer` 3.5.0 → 4.1.2) не принят к слиянию.**
|
||||
|
||||
Зелёные проверки на #45 и #46 про релиз ничего не доказывают:
|
||||
`linux-release.yml` запускается только по `push` тега `v*` и по
|
||||
`workflow_dispatch` (строки 3–12), на pull request он не выполняется вовсе.
|
||||
Мажорная смена installer меняет версию cosign у producer, а
|
||||
`deploy/ochenstarik-server-monitor-manager.sh:34` фиксирует у consumer
|
||||
`COSIGN_VERSION="v3.1.3"` с проверкой SHA-256. Какую версию cosign ставит
|
||||
installer 4.1.2 по умолчанию — не проверял, это не определено.
|
||||
`docs/release-policy.md` показывает четыре поломки контракта
|
||||
producer/consumer по cosign: alpha.12, alpha.13, alpha.17, alpha.18.
|
||||
|
||||
Предлагаю до слияния #45 прогнать `Release pipeline` через
|
||||
`workflow_dispatch` на репетиционном теге — с оговоркой из
|
||||
`agents/claude/notes/2026-08-18-передача-состояния.md`: репетиция идёт по
|
||||
`refs/heads/main` и пропускает шаги под условием `refs/tags/*`, так был
|
||||
сожжён alpha.19. Значит проверять нужно ещё и то, что нужные шаги вообще
|
||||
исполнялись.
|
||||
|
||||
Второй вопрос: обновлять ли NuGet отдельным заданием на машине с .NET SDK.
|
||||
104
agents/claude/done/2026-08-18-git-sync.md
Normal file
104
agents/claude/done/2026-08-18-git-sync.md
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# Отчёт: синхронизация git-состояния репозитория
|
||||
|
||||
- **Задание:** `../inbox/2026-08-18-git-sync.md`
|
||||
- **Агент:** `claude`
|
||||
- **Дата:** 2026-08-18
|
||||
- **Ветка / коммиты:** `claude/deps-update`, ответвлена от `23eb3f5`
|
||||
(`chore/agents-workspace`). Изменений кода в рамках этой задачи нет.
|
||||
|
||||
## Что сделано
|
||||
|
||||
Выполнена синхронизация с `origin` и снято фактическое состояние. Файлы
|
||||
репозитория этой задачей не менялись — сводить оказалось нечего.
|
||||
|
||||
Установлено:
|
||||
|
||||
- `git fetch --all --prune` подтянул одну новую удалённую ветку
|
||||
`origin/antigravity/alpha12-ci-fix`; удалённых на сервере веток,
|
||||
подлежащих очистке локально, не было;
|
||||
- локальная `main` и `origin/main` — один и тот же коммит `f8e751c`;
|
||||
- `chore/agents-workspace` опережает `origin/main` на 2 коммита и не отстаёт
|
||||
ни на один: `git merge-base origin/main HEAD` = `f8e751c` = `origin/main`.
|
||||
Вливать `main` в ветку не требуется;
|
||||
- незапушенных локальных коммитов и stash нет.
|
||||
|
||||
Состояние открытых PR на 2026-08-18:
|
||||
|
||||
| PR | Ветка | Слияние | Проверки |
|
||||
|----|-------|---------|----------|
|
||||
| #64 | `chore/agents-workspace` | `CLEAN` | 4/4 успешно |
|
||||
| #63 | `antigravity/console-links` | `BEHIND` — отстала от `main` | 12/12 успешно |
|
||||
| #46 | `dependabot/.../download-artifact-8.0.1` | `CLEAN` | 4/4 успешно |
|
||||
| #45 | `dependabot/.../cosign-installer-4.1.2` | `CLEAN` | 4/4 успешно |
|
||||
| #44 | `dependabot/.../setup-qemu-action-4.2.0` | `CLEAN` | 4/4 успешно |
|
||||
|
||||
Удалённые ветки, полностью влитые в `origin/main` и пригодные к удалению:
|
||||
`antigravity/desktop-update-proof`, `antigravity/node-enrollment-endpoint`,
|
||||
`antigravity/password-login`, `antigravity/web-console`,
|
||||
`codex/cosign-provisioning`, `codex/release-alpha16-cosign-verification`,
|
||||
`codex/release-alpha17-machine-output`,
|
||||
`codex/release-alpha18-cosign-negative-test`, `codex/release-alpha20`,
|
||||
`codex/uninstall-mode` — 10 веток.
|
||||
|
||||
Не влита и при этом не имеет открытого PR: `antigravity/alpha12-ci-fix`.
|
||||
Её назначение не определено.
|
||||
|
||||
## Как проверено
|
||||
|
||||
```
|
||||
$ git fetch --all --prune
|
||||
From https://github.com/ochenstarik-ui/server-monitor-manager
|
||||
* [new branch] antigravity/alpha12-ci-fix -> origin/antigravity/alpha12-ci-fix
|
||||
|
||||
$ git rev-parse main origin/main
|
||||
f8e751c4bc827b18c6834063cd2742e832d798d9
|
||||
f8e751c4bc827b18c6834063cd2742e832d798d9
|
||||
|
||||
$ git merge-base origin/main HEAD
|
||||
f8e751c4bc827b18c6834063cd2742e832d798d9
|
||||
|
||||
$ git log --oneline HEAD..origin/main
|
||||
(пусто)
|
||||
|
||||
$ git log --oneline origin/main..HEAD
|
||||
23eb3f5 chore(agents): разбор рабочих папок с диска на 2026-08-18
|
||||
26c60a3 chore(agents): единая структура заданий и приёмки
|
||||
|
||||
$ git stash list
|
||||
(пусто)
|
||||
|
||||
$ git log --branches --not --remotes --oneline
|
||||
(пусто)
|
||||
```
|
||||
|
||||
## Что не сделано
|
||||
|
||||
- PR не слиты и ветки не запушены: по `AGENTS.md` это делает главный агент,
|
||||
и владелец отдельного подтверждения не давал;
|
||||
- 10 влитых удалённых веток не удалены — удаление на `origin` необратимо
|
||||
и требует подтверждения владельца;
|
||||
- PR #63 не переведён в актуальное состояние относительно `main`: это ветка
|
||||
агента `antigravity`, чужую работу не трогаю.
|
||||
|
||||
## Замечено рядом
|
||||
|
||||
Вне границ задачи; предлагаю отдельными заданиями.
|
||||
|
||||
1. **CHANGELOG отстал на 14 релизов.** `CHANGELOG.md` заканчивается на
|
||||
`v0.1.0-alpha.6` (2026-07-31), теги идут до `v0.1.0-alpha.20`
|
||||
(2026-08-18). Секция `Unreleased` ссылается на давно слитые #10–#12.
|
||||
2. **README называет неверную текущую версию.** `README.md:101` —
|
||||
«`v0.1.0-alpha.14` is an early testing release».
|
||||
3. **`docs/release-policy.md` доведён до alpha.19**, запись про alpha.20
|
||||
отсутствует, хотя документ ведёт построчную историю каждой версии.
|
||||
4. **`docs/roadmap.md` не отражает слитые в `main` подсистемы**: web console,
|
||||
password login для консоли, uninstall mode, unified installer.
|
||||
5. **Ветка `antigravity/alpha12-ci-fix`** висит без PR — либо оформить PR,
|
||||
либо удалить.
|
||||
|
||||
## Вопросы к приёмке
|
||||
|
||||
- Удалять ли 10 влитых удалённых веток и кем — этим же заданием или
|
||||
отдельным?
|
||||
- Нужно ли обновлять PR #63 относительно `main` силами `claude`, или это
|
||||
возвращается автору ветки?
|
||||
87
agents/claude/done/2026-08-20-docs-sync.md
Normal file
87
agents/claude/done/2026-08-20-docs-sync.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Отчёт: документация приведена в соответствие с историей релизов
|
||||
|
||||
- **Задание:** `../inbox/2026-08-20-docs-sync.md`
|
||||
- **Агент:** `claude`
|
||||
- **Дата:** 2026-08-20
|
||||
- **Ветка:** `claude/deps-update`
|
||||
|
||||
## Что сделано
|
||||
|
||||
**`CHANGELOG.md`.** Дописаны 14 отсутствовавших версий, alpha.7 … alpha.20.
|
||||
Записи выведены из тегов и коммитов между ними, а не из памяти. Прежняя
|
||||
секция `Unreleased` со ссылками на #10–#12 оказалась содержимым alpha.7 —
|
||||
перенесена туда. Новый `Unreleased` описывает слитое после alpha.20: #63,
|
||||
#64, #44, #46. Ссылки сравнения версий перестроены для всех 20 тегов.
|
||||
|
||||
Сожжённые номера помечены прямо в заголовке — `burned, not published` — с
|
||||
указанием, чем упал пайплайн и под какой версией вышло их содержимое:
|
||||
|
||||
- alpha.10 и alpha.11 — пайплайн упал до публикации;
|
||||
- alpha.19 — `DEFAULT_RELEASE_TAG` в упакованном установщике не совпал
|
||||
с тегом; содержимое вышло под alpha.20.
|
||||
|
||||
Для опубликованных, но дефектных версий записи содержат сам дефект:
|
||||
alpha.8 (осиротевшая подпись без manifest v2), alpha.12 и alpha.13
|
||||
(подпись без сертификата Fulcio), alpha.14 (проверяемая, но не
|
||||
устанавливаемая на чистый хост), alpha.15 … alpha.17 (на чём остановилась
|
||||
проверка). Иначе CHANGELOG подсказывал бы ставить версию, которая не
|
||||
ставится.
|
||||
|
||||
**`docs/release-policy.md`.** Добавлена запись про alpha.20 — что он
|
||||
исправляет, что переносит из сожжённого alpha.19.
|
||||
|
||||
**`docs/roadmap.md`.** Веб-консоли в плане не было вовсе, поэтому это не
|
||||
переключение галочек, а дописывание фактически поставленного. В этап 2:
|
||||
консоль оператора, отдача ассетов из встроенных ресурсов, вход по паролю
|
||||
для тестовых стендов. В этап 3: управление Links из консоли, аварийное
|
||||
отключение, раздельные желаемое/фактическое состояния, журнал событий.
|
||||
В этап 7: режим полного удаления сервера, пошаговый объединённый установщик.
|
||||
|
||||
## Как проверено
|
||||
|
||||
Все 20 версий на месте:
|
||||
|
||||
```
|
||||
$ grep -c "^## \[v0.1.0-alpha" CHANGELOG.md
|
||||
20
|
||||
```
|
||||
|
||||
Даты записей сверены с датами тегов — расхождений нет:
|
||||
|
||||
```
|
||||
$ for n in $(seq 1 20); do t="v0.1.0-alpha.$n"; ... done
|
||||
v0.1.0-alpha.1 2026-07-16 2026-07-16 совпадает
|
||||
...
|
||||
v0.1.0-alpha.20 2026-08-18 2026-08-18 совпадает
|
||||
```
|
||||
|
||||
Двадцать строк, все «совпадает».
|
||||
|
||||
## Что не сделано
|
||||
|
||||
**README и одиннадцать переводов не тронуты намеренно.** `README.md:101`
|
||||
по-прежнему называет `v0.1.0-alpha.14`. `docs/release-policy.md` отдаёт
|
||||
строку статуса релиза в корневом README и в переводах в единоличное
|
||||
владение владельцу релиза и прямо требует запрашивать изменение, а не
|
||||
править самому. Запрошено заданием
|
||||
`agents/codex/inbox/2026-08-20-readme-release-status.md`.
|
||||
|
||||
Порядок регламента нарушен: задание в `inbox/` записано после выполнения
|
||||
работы, а не до. Указываю прямо, чтобы это не выглядело соблюдённым.
|
||||
|
||||
## Замечено рядом
|
||||
|
||||
1. **`README.md:101` и переводы** — предмет выданного задания Codex.
|
||||
2. **В roadmap этап 6 содержит пункт «синхронизировать все переводы README
|
||||
с текущим release status»** — он остаётся невыполненным и закрывается
|
||||
тем же заданием.
|
||||
3. **Содержание записей CHANGELOG выведено из заголовков коммитов и
|
||||
merge-коммитов.** Там, где заголовок был неинформативен, запись вышла
|
||||
короче фактического объёма работы. Это не выдумка, но и не полный
|
||||
пересказ: восстановление постфактум точнее заголовков быть не может.
|
||||
|
||||
## Вопросы к приёмке
|
||||
|
||||
Записи alpha.10, alpha.11 и alpha.19 оставлены в CHANGELOG как сожжённые.
|
||||
Альтернатива — не упоминать их вовсе. Считаю упоминание правильным:
|
||||
читатель, увидев разрыв в нумерации, иначе решит, что запись потеряна.
|
||||
45
agents/claude/inbox/2026-08-18-deps-update.md
Normal file
45
agents/claude/inbox/2026-08-18-deps-update.md
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Обновление зависимостей: GitHub Actions и NuGet
|
||||
|
||||
- **Кому:** `claude`
|
||||
- **Дата:** 2026-08-18
|
||||
- **От кого:** владелец проекта (задание получено в чате: «актуализируй проект»,
|
||||
уточнено выбором «Обновить зависимости»)
|
||||
- **Ветка:** `claude/deps-update`
|
||||
- **Файл отчёта:** `../done/2026-08-18-deps-update.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Закрыть отставание зависимостей:
|
||||
|
||||
1. GitHub Actions — три открытых PR от Dependabot (#44 `docker/setup-qemu-action`
|
||||
3.7.0 → 4.2.0, #45 `sigstore/cosign-installer` 3.5.0 → 4.1.2,
|
||||
#46 `actions/download-artifact` 4.1.8 → 8.0.1).
|
||||
2. NuGet — версии в `Directory.Packages.props` и `Directory.Build.props`
|
||||
против актуальных на nuget.org.
|
||||
|
||||
## Границы
|
||||
|
||||
Не мержить PR Dependabot и не пушить ветку без подтверждения владельца.
|
||||
Не менять способ закрепления действий (tag → SHA) — это отдельная задача,
|
||||
даже если несоответствие очевидно. Не править код проекта, документацию
|
||||
и CHANGELOG.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- Обновлённые SHA в `.github/workflows/` совпадают с SHA из соответствующих
|
||||
веток Dependabot: `git diff origin/main...origin/dependabot/...`;
|
||||
- `grep -rn "uses:" .github/workflows/` — в дереве не осталось старых версий;
|
||||
- для NuGet: `dotnet list package --outdated` и восстановление
|
||||
`packages.lock.json` (`RestorePackagesWithLockFile=true`,
|
||||
в CI `-p:RestoreLockedMode=true`).
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Релизная подпись зависит от cosign: `deploy/ochenstarik-server-monitor-manager.sh`
|
||||
закрепляет потребительский `COSIGN_VERSION="v3.1.3"` с проверкой SHA-256,
|
||||
а CI ставит cosign через `sigstore/cosign-installer` без закрепления версии
|
||||
cosign. `docs/release-policy.md` (alpha.17, alpha.18) описывает, что контракт
|
||||
producer/consumer по cosign уже ломался. Смена версии installer — решение
|
||||
владельца, не самостоятельное.
|
||||
|
||||
Наличие .NET SDK на рабочей машине на момент постановки задачи не определено.
|
||||
34
agents/claude/inbox/2026-08-18-git-sync.md
Normal file
34
agents/claude/inbox/2026-08-18-git-sync.md
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Синхронизация git-состояния репозитория
|
||||
|
||||
- **Кому:** `claude`
|
||||
- **Дата:** 2026-08-18
|
||||
- **От кого:** владелец проекта (задание получено в чате: «актуализируй проект»,
|
||||
уточнено выбором «Синхронизировать git»)
|
||||
- **Ветка:** `claude/deps-update`
|
||||
- **Файл отчёта:** `../done/2026-08-18-git-sync.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Установить фактическое расхождение локального репозитория и `origin`, свести
|
||||
локальные ветки со свежим `main` и предъявить состояние открытых PR и
|
||||
удалённых веток: что влито, что отстало, что можно удалять.
|
||||
|
||||
## Границы
|
||||
|
||||
Не пушить, не мержить PR, не удалять удалённые ветки без отдельного
|
||||
подтверждения владельца. Не трогать ветки других агентов
|
||||
(`antigravity/*`, `codex/*`, `hermes/*`). Не править документацию —
|
||||
рассинхрон CHANGELOG/README/roadmap с фактическим состоянием релизов
|
||||
вынесен из этой задачи и идёт в отчёт списком.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- `git fetch --all --prune` — выполнен;
|
||||
- `git rev-parse main origin/main` — совпадают;
|
||||
- `git log --oneline HEAD..origin/main` — пусто (нечего вливать);
|
||||
- `git branch -r --merged origin/main` — список влитых веток приведён в отчёте.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
`AGENTS.md`: в `main` пушит и принимает работу только главный агент.
|
||||
Ветка ведётся с префиксом `claude/` согласно таблице в `agents/README.md`.
|
||||
41
agents/claude/inbox/2026-08-20-docs-sync.md
Normal file
41
agents/claude/inbox/2026-08-20-docs-sync.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
# Привести документацию в соответствие с фактическим состоянием релизов
|
||||
|
||||
- **Кому:** `claude`
|
||||
- **Дата:** 2026-08-20
|
||||
- **От кого:** владелец проекта (в чате: «делай что можно. и продолжай»)
|
||||
- **Ветка:** `claude/deps-update`
|
||||
- **Файл отчёта:** `../done/2026-08-20-docs-sync.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
`CHANGELOG.md` заканчивался на `v0.1.0-alpha.6` от 2026-07-31, тогда как
|
||||
теги идут до `v0.1.0-alpha.20`. Секция `Unreleased` ссылалась на давно
|
||||
слитые #10–#12. `docs/release-policy.md` вёл построчную историю версий, но
|
||||
обрывался на alpha.19. `docs/roadmap.md` не отражал подсистемы, слитые в
|
||||
`main`.
|
||||
|
||||
Восстановить историю по фактам репозитория — тегам и коммитам между ними,
|
||||
а не по памяти:
|
||||
|
||||
- CHANGELOG: записи для alpha.7 … alpha.20, сожжённые номера помечены как
|
||||
сожжённые, ссылки сравнения версий выправлены;
|
||||
- release-policy: запись про alpha.20;
|
||||
- roadmap: отметить фактически поставленное.
|
||||
|
||||
## Границы
|
||||
|
||||
Не менять код, workflow и версии сборки. **Не трогать строку статуса релиза
|
||||
в README и переводах**: по `docs/release-policy.md` эти пути принадлежат
|
||||
владельцу релиза, изменение запрашивается заданием, а не правится напрямую.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- в CHANGELOG присутствуют все 20 версий: `grep -c "^## \[v0.1.0-alpha"`;
|
||||
- даты записей совпадают с датами тегов: `git log -1 --format=%ad --date=short <тег>`;
|
||||
- содержание записей выводится из `git log` между соседними тегами.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Сожжённые номера `alpha.10`, `alpha.11`, `alpha.19` не переиспользуются:
|
||||
теги существуют, релизы не опубликованы. Запись о них в CHANGELOG обязана
|
||||
показывать это прямо, иначе читатель решит, что релиз был.
|
||||
114
agents/claude/notes/2026-08-18-передача-состояния.md
Normal file
114
agents/claude/notes/2026-08-18-передача-состояния.md
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
# Передача состояния: как продолжить работу в новом чате
|
||||
|
||||
Этот файл заменяет переписку. Он написан для того, чтобы новый чат начинался
|
||||
с одного сообщения и не требовал пересказа истории.
|
||||
|
||||
## Первое сообщение в новом чате
|
||||
|
||||
> Репозиторий `C:\Users\Ochenstarik\Agent_projects\server-monitor-manager`,
|
||||
> GitHub `ochenstarik-ui/server-monitor-manager`.
|
||||
> Прочитай `agents/README.md` и `agents/claude/notes/2026-08-18-передача-состояния.md`,
|
||||
> сверь состояние с GitHub и продолжай как главный агент: проверяешь работу
|
||||
> Codex и Antigravity, пишешь им задания, мержишь и выпускаешь релизы.
|
||||
|
||||
Больше ничего пересказывать не нужно: доска, задания, отчёты и архив лежат
|
||||
в репозитории.
|
||||
|
||||
## Где что лежит
|
||||
|
||||
| Что | Где |
|
||||
|---|---|
|
||||
| Правила работы агентов | `agents/README.md` |
|
||||
| Задания агенту | `agents/<agent>/inbox/` |
|
||||
| Отчёты агента | `agents/<agent>/done/` |
|
||||
| Принятые пары «задание — отчёт» | `agents/_accepted/ГГГГ-ММ-ДД-имя/` |
|
||||
| Доска состояния (прежний формат) | `agents/_salvage-2026-08-18/smm-deliverables/README.md` |
|
||||
| Архив закрытых заданий | `agents/_salvage-2026-08-18/smm-deliverables/Старые задачи/` |
|
||||
| Инструкция владельцу по серверам | `agents/_salvage-2026-08-18/smm-deliverables/smm-cleanup-and-install-2026-08-15.md` |
|
||||
|
||||
Доску стоит перенести из `_salvage` в постоянное место — она живая, а не архив.
|
||||
|
||||
## Состояние на 2026-08-18
|
||||
|
||||
- `main` — `f8e751c`, слит PR #62 `codex/release-alpha20`;
|
||||
- последний релиз — `v0.1.0-alpha.20`;
|
||||
- открыты: PR #63 `antigravity/console-links` (управление Links в консоли),
|
||||
PR #64 `chore/agents-workspace` (эта самая схема папок), плюс dependabot;
|
||||
- ветка `claude/deps-update` содержит незакоммиченные правки двух workflow
|
||||
и два новых задания в `agents/claude/inbox/`.
|
||||
|
||||
### Сожжённые номера версий
|
||||
|
||||
`alpha.10`, `alpha.11`, `alpha.19` — теги созданы, `Release pipeline` упал,
|
||||
релизы не опубликованы, номера не переиспользуются.
|
||||
|
||||
`alpha.19` сожжён при мне и по процедурной дыре, а не по вине исполнителя:
|
||||
шаг `Package bootstrap` сверяет `DEFAULT_RELEASE_TAG` в `deploy/smm-setup.sh`
|
||||
с выпускаемым тегом, но весь блок закрыт условием `refs/tags/*`, поэтому
|
||||
репетиция через `workflow_dispatch` идёт по `refs/heads/main` и эту сверку
|
||||
пропускает. Репетиция была зелёной, тег упал.
|
||||
|
||||
**Вывод, который дороже самого случая:** репетиция, не покрывающая шаги,
|
||||
исполняемые только на теге, не является репетицией. Проверять это до
|
||||
следующего выпуска.
|
||||
|
||||
## Рабочие соглашения
|
||||
|
||||
Выведены из происшествий, а не из общих соображений.
|
||||
|
||||
1. **Задание содержит только предстоящую работу.** Файлы, начинавшиеся
|
||||
с описания уже сделанного, исполнитель принимал за отчёт о выполнении:
|
||||
Codex ответил «задание уже выполнено, PR #58» вместо работы над
|
||||
невыполненной частью. Сделанное живёт на доске, а не в задании.
|
||||
2. **Отчёт — раздел в описании PR.** Отдельный файл с отчётом результатом
|
||||
не является. Antigravity однажды сдал только такой файл, не создав ни ветки,
|
||||
ни PR.
|
||||
3. **Проверять по репозиторию, а не по отчёту.** Смотреть диф от базы слияния,
|
||||
а не от `main`: отставшая ветка в обычном дифе выглядит так, будто удаляет
|
||||
чужую работу.
|
||||
4. **Критерий приёмки должен быть достижим.** «Проверка запустилась
|
||||
автоматически» была недостижима: событие от `GITHUB_TOKEN` не запускает
|
||||
другие workflow. Это дефект задания, а не исполнителя.
|
||||
5. **Границы областей прописывать явно.** Codex — `deploy/**`, релизный
|
||||
пайплайн, проверка релиза. Antigravity — `src/**`, консоль, тесты Control
|
||||
и Desktop. Пересечение областей ломает параллельную работу.
|
||||
6. **Зелёный CI не означает работающую машину.** Так найдены: отсутствующий
|
||||
cosign, права на каталог mesh, отдача ассетов из ресурсов сборки. Каждый раз
|
||||
тест подставлял временный путь и проходил, а на сервере отказывало.
|
||||
7. **Команды владельцу помечать, где выполнять**: 🖥 на Windows, 🐧 на сервере.
|
||||
Путаница машин стоила нескольких заходов.
|
||||
8. **Долгие загрузки — с индикатором.** Молчащий `curl -fsSL` на 24 МБ дважды
|
||||
принят за зависание и прерван.
|
||||
|
||||
## Живая установка
|
||||
|
||||
Проверено на настоящих машинах, а не в CI.
|
||||
|
||||
- **Hub** `178.212.13.102` (`host1885995-3.hostland.pro`), Ubuntu 24.04 x86_64,
|
||||
поставлен из `v0.1.0-alpha.14`;
|
||||
- отпечаток CA:
|
||||
`EB:05:E5:16:42:EE:97:28:C2:E9:EA:6F:3E:48:3C:0C:1C:1E:02:E0:ED:9B:AF:7B:BF:24:2C:19:D4:4B:11:C4`;
|
||||
- публичный ключ WireGuard Hub: `AjN8XwPB11bRQa0fO5ljPlAWc0FxU+fxbeUT8AZczHk=`;
|
||||
- **Node `ai-agent`** — `vm1957808.vds.chsl.one`, адрес `10.77.0.2`, mesh собран,
|
||||
ping 7.6 мс. На этой машине работает 3x-ui и он не пострадал;
|
||||
- свободных серверов больше нет. `tests/acceptance/three-server-mesh.sh` требует
|
||||
Hub и три узла: источник и две цели, потому что смысл проверки в том, что
|
||||
к одной цели доступ по Link открыт, а ко второй закрыт. На двух машинах
|
||||
это не проверить;
|
||||
- WSL под узлы не годится: все дистрибутивы WSL2 делят один сетевой стек,
|
||||
два `smm0` с разными адресами не поднять. Проверено экспериментом.
|
||||
|
||||
**Физическая приёмка — единственный пункт Горизонта 0, не закрываемый кодом.**
|
||||
|
||||
## Что важно знать про продукт
|
||||
|
||||
- подпись релиза проверяется настоящим материалом с обеих сторон: установкой
|
||||
на чистый runner (Linux) и `UpdateService` (Windows), автоматически на каждом
|
||||
релизе;
|
||||
- проверка подписи требует исходящего доступа к службам sigstore; в закрытом
|
||||
контуре установка зависнет;
|
||||
- таблица nftables `inet ochenstarik_smm` цепляется только к хуку `forward`
|
||||
и только к трафику `smm0 → smm0`. Хука `input` в ней нет, политика `accept`.
|
||||
Поэтому установка на сервер с 3x-ui безопасна — проверено на живой машине;
|
||||
- опубликованный тег неизменяем, ассеты не заменяются: исправление выпускается
|
||||
следующим номером.
|
||||
85
agents/codex/inbox/2026-08-19-cosign-installer-rehearsal.md
Normal file
85
agents/codex/inbox/2026-08-19-cosign-installer-rehearsal.md
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Доказать или отклонить обновление cosign-installer до 4.1.2
|
||||
|
||||
- **Кому:** `codex`
|
||||
- **Дата:** 2026-08-19
|
||||
- **От кого:** главный агент (`claude`)
|
||||
- **Ветка:** `codex/cosign-installer-rehearsal`
|
||||
- **Файл отчёта:** `../done/2026-08-19-cosign-installer-rehearsal.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
Открыт PR #45: `sigstore/cosign-installer` 3.5.0 → 4.1.2 в
|
||||
`.github/workflows/linux-release.yml`, два вхождения (строки 26 и 253).
|
||||
Слиянию он не подлежит, пока не предъявлено доказательство, что подпись
|
||||
релиза после смены версии остаётся проверяемой. Нужно это доказательство —
|
||||
либо обоснованный отказ от обновления.
|
||||
|
||||
Ответить требуется на три вопроса, каждый — фактом, а не рассуждением:
|
||||
|
||||
1. **Какую версию cosign ставит `cosign-installer@v4.1.2` по умолчанию.**
|
||||
В workflow версия cosign не закреплена (`cosign-release` не задан), так
|
||||
что она определяется installer'ом. Сейчас это не определено.
|
||||
2. **Совместим ли формат подписи, которую произведёт этот cosign, с
|
||||
потребителями — обоими.** Потребителей два, и они на разных версиях
|
||||
cosign:
|
||||
|
||||
- **Linux.** `deploy/ochenstarik-server-monitor-manager.sh:34` закрепляет
|
||||
`COSIGN_VERSION="v3.1.3"` с проверкой SHA-256 и проверяет подпись через
|
||||
`cosign verify-blob` с отдельным сертификатом Fulcio.
|
||||
- **Windows.** `src/ServerMonitorManager.Desktop/UpdateService.cs:79`
|
||||
закрепляет `CosignVersion = "v2.4.0"` с закреплённым SHA-256
|
||||
(`ProcessSignatureVerifier`), скачивает `cosign-windows-amd64.exe` и
|
||||
выполняет тот же `verify-blob --certificate … --certificate-identity-regexp
|
||||
…@refs/tags/v.*`.
|
||||
|
||||
То есть подпись одного релиза проверяется cosign v3.1.3 на Linux и cosign
|
||||
v2.4.0 на Windows. Смена версии у producer должна оставить проверяемым
|
||||
**оба** пути, а не только тот, который гоняет Release Verification.
|
||||
Разъезд producer и consumer по cosign — ровно то, на чём проект уже
|
||||
потерял alpha.12, alpha.13, alpha.17 и alpha.18.
|
||||
3. **Проходит ли полный релизный путь.** Прогнать `Release pipeline` на
|
||||
репетиционном теге и предъявить, что подпись произведена, а
|
||||
`Release Verification` её проверила на чистом хосте.
|
||||
|
||||
## Границы
|
||||
|
||||
Только `.github/workflows/linux-release.yml`, `deploy/**` и релизные тесты.
|
||||
Не трогать `src/**`, консоль, Desktop и `agents/` кроме своих папок.
|
||||
Не выпускать настоящий релиз и не двигать существующие теги.
|
||||
|
||||
Если по ходу выяснится, что для доказательства нужно закрепить версию
|
||||
cosign явно (`cosign-release`) или перевести действие с тега на SHA — это
|
||||
**предложение в отчёт**, а не самовольная правка: закрепление
|
||||
cosign-installer тегом вместо SHA уже числится отдельным замечанием.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- ссылки на прогоны `Release pipeline` и `Release Verification` с
|
||||
репетиционным тегом и их фактический итог;
|
||||
- **отдельно — проверка подписи потребителем на cosign v2.4.0**, как это
|
||||
делает Windows-обновлятор. Release Verification гоняет только Linux-путь,
|
||||
поэтому Windows-потребитель ею не покрыт;
|
||||
- вывод шага, который печатает версию установленного cosign;
|
||||
- вывод проверки подписи потребителем.
|
||||
|
||||
**Отдельное требование, из-за которого задание и появилось.** Репетиция
|
||||
через `workflow_dispatch` идёт по `refs/heads/main`, поэтому шаги, закрытые
|
||||
условием `refs/tags/*`, в ней не исполняются. Так был сожжён `alpha.19`:
|
||||
репетиция была зелёной, а на теге упала сверка `DEFAULT_RELEASE_TAG`.
|
||||
В отчёте требуется явно показать, какие шаги при репетиции исполнялись, а
|
||||
какие пропущены — списком. Зелёная репетиция без этого списка
|
||||
доказательством не считается.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
`docs/release-policy.md` фиксирует четыре поломки контракта
|
||||
producer/consumer по cosign: alpha.12 (подпись без сертификата Fulcio),
|
||||
alpha.13 (то же), alpha.17 (cosign v3 потребовал явный bundle или legacy
|
||||
detached-output), alpha.18 (исправление негативного теста под detached-output).
|
||||
Пятая поломка обойдётся ещё в один сожжённый номер версии.
|
||||
|
||||
Сожжённые номера — `alpha.10`, `alpha.11`, `alpha.19`; они не
|
||||
переиспользуются.
|
||||
|
||||
Приемлемый результат задания — «обновление отклонено, причина такая-то».
|
||||
Неприемлемый — «обновил, CI зелёный».
|
||||
63
agents/codex/inbox/2026-08-20-msix-version-stuck.md
Normal file
63
agents/codex/inbox/2026-08-20-msix-version-stuck.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# Версия MSIX не менялась 14 релизов подряд
|
||||
|
||||
- **Кому:** `codex`
|
||||
- **Дата:** 2026-08-20
|
||||
- **От кого:** главный агент (`claude`)
|
||||
- **Ветка:** `codex/msix-version`
|
||||
- **Файл отчёта:** `../done/2026-08-20-msix-version-stuck.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
`src/ServerMonitorManager.Desktop/Package.appxmanifest:13` содержит
|
||||
`Version="1.0.0.6"`. Последний раз её меняли 2026-07-31 коммитом `c320b7d`
|
||||
«chore(release): bump MSIX version to 1.0.0.6 (#9)» — то есть под
|
||||
`v0.1.0-alpha.6`. С тех пор выпущено четырнадцать версий, вплоть до
|
||||
`v0.1.0-alpha.20`, и в каждой из них MSIX объявляет себя как `1.0.0.6`.
|
||||
|
||||
Windows различает пакеты по версии в манифесте, а не по имени файла и не по
|
||||
тегу GitHub. Установка нового MSIX поверх уже установленного с той же
|
||||
версией не считается обновлением.
|
||||
|
||||
Нужно:
|
||||
|
||||
1. Определить фактическое поведение: устанавливается ли MSIX из alpha.20
|
||||
поверх установленного MSIX из alpha.14, и что именно происходит.
|
||||
Пока это **не определено** — я проверял чтением дерева, не установкой.
|
||||
2. Если обновление действительно не проходит — связать версию пакета с
|
||||
версией релиза, чтобы она поднималась при каждом выпуске автоматически,
|
||||
а не руками.
|
||||
3. Учесть, что `UpdateService` сравнивает версию манифеста с именем тега
|
||||
релиза (`UpdateService.cs:256–262`), а не с версией пакета. Значит
|
||||
обновлятор может считать обновление доступным и скачать MSIX, который
|
||||
Windows затем откажется ставить. Проверить эту связку целиком.
|
||||
|
||||
## Границы
|
||||
|
||||
`Package.appxmanifest`, скрипты сборки Windows-установщика
|
||||
(`build/windows/**`) и, если потребуется, `windows-release.yml`. Не менять
|
||||
логику `UpdateService` без отдельного основания: сначала измерение, потом
|
||||
правка. Не трогать `src/**` вне Desktop, консоль и Linux-часть.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- вывод `Get-AppxPackage` до и после установки: версия должна отличаться;
|
||||
- показать установку MSIX новой версии поверх предыдущей на машине, где
|
||||
предыдущая уже стоит, и её фактический результат;
|
||||
- если решение автоматизирует поднятие версии — показать два прогона сборки
|
||||
с разными тегами и разные версии в получившихся манифестах.
|
||||
|
||||
«Версия теперь поднимается» без установки поверх предыдущей результатом
|
||||
проверки не является: проблема ровно в установке.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Дефект найден чтением дерева и истории git, установка не выполнялась: на
|
||||
машине разбора нет ни .NET SDK, ни установленного пакета. Если при проверке
|
||||
окажется, что Windows нормально ставит MSIX той же версии поверх себя, —
|
||||
так и напиши с выводом команд; это допустимый результат.
|
||||
|
||||
MSIX подписан тестовым сертификатом (`Publisher="CN=AppPublisher"`,
|
||||
ассет `ServerMonitorManager-test-signing.cer`), поэтому для установки нужен
|
||||
импорт этого сертификата в доверенные корневые. Постоянная доверенная
|
||||
Windows code-signing identity в `docs/roadmap.md` числится невыполненной
|
||||
(этап 6). Это отдельная задача, здесь её решать не нужно.
|
||||
52
agents/codex/inbox/2026-08-20-readme-release-status.md
Normal file
52
agents/codex/inbox/2026-08-20-readme-release-status.md
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Синхронизировать release status в README и переводах
|
||||
|
||||
- **Кому:** `codex`
|
||||
- **Дата:** 2026-08-20
|
||||
- **От кого:** главный агент (`claude`)
|
||||
- **Ветка:** `codex/readme-release-status`
|
||||
- **Файл отчёта:** `../done/2026-08-20-readme-release-status.md`
|
||||
|
||||
## Что нужно сделать
|
||||
|
||||
`README.md:101` утверждает, что текущий тестовый выпуск — `v0.1.0-alpha.14`.
|
||||
Фактически опубликован `v0.1.0-alpha.20`. Те же строки статуса в
|
||||
одиннадцати переводах `docs/i18n/README.*.md` рассинхронизированы между
|
||||
собой и с корневым README.
|
||||
|
||||
Привести строку статуса релиза к `v0.1.0-alpha.20` в корневом README и во
|
||||
всех переводах.
|
||||
|
||||
Задание адресовано тебе, а не выполнено мной, по прямому требованию
|
||||
`docs/release-policy.md`: владелец релиза имеет единоличное право записи в
|
||||
version sources, `deploy/**`, `tests/bootstrap/**`, релизные workflow, строку
|
||||
статуса релиза в корневом README и в переводах. Остальные просят об
|
||||
изменении в отчёте и не правят эти пути сами.
|
||||
|
||||
Это же закрывает пункт этапа 6 в `docs/roadmap.md`: «синхронизировать все
|
||||
переводы README с текущим release status». Отметить его выполненным —
|
||||
часть задания.
|
||||
|
||||
## Границы
|
||||
|
||||
Только строки статуса релиза в README и переводах плюс соответствующий
|
||||
пункт в `docs/roadmap.md`. Не переписывать остальной текст переводов, не
|
||||
трогать `CHANGELOG.md` и `docs/release-policy.md` — они уже приведены в
|
||||
соответствие отдельной работой. Не менять `DEFAULT_RELEASE_TAG` и версии
|
||||
сборки: релиз этим заданием не выпускается.
|
||||
|
||||
## Как проверить результат
|
||||
|
||||
- `grep -rn "alpha\." README.md docs/i18n/` — ни одной ссылки на версию
|
||||
ниже `v0.1.0-alpha.20` в строках статуса; вывод команды в отчёт;
|
||||
- перечислить в отчёте все двенадцать файлов с указанием, какая версия в
|
||||
каждом стояла до правки. Если где-то стояла не `alpha.14`, а другая — это
|
||||
само по себе результат, его надо показать;
|
||||
- `bash tests/bootstrap/test-release-contract.sh` — зелёный, если он
|
||||
затрагивает README;
|
||||
- прогоны CI на PR — ссылками.
|
||||
|
||||
## Контекст и ограничения
|
||||
|
||||
Проверка выполнена мной чтением дерева, а не запуском сборки: на машине
|
||||
разбора нет .NET SDK. Возможно, какой-то из переводов уже актуален —
|
||||
я сверял только корневой README и не открывал все одиннадцать файлов.
|
||||
|
|
@ -21,5 +21,6 @@ Known release history:
|
|||
- `v0.1.0-alpha.17` keeps checksum verification fail-closed while suppressing its success line, so pass-through commands such as `node-code` return only their machine-readable bootstrap output. Its automatic verification completed the clean-host Hub and Node installation, then the negative-test harness stopped while creating a wrong-identity signature because cosign v3 requires an explicit bundle or legacy detached-output mode. The immutable release and failed harness run remain as evidence; the negative test is corrected in the next version.
|
||||
- `v0.1.0-alpha.18` makes the wrong-identity negative test select cosign v3's explicit detached-output mode, matching the production consumer's detached signature and certificate contract. It is the first release required to complete both automatic `workflow_run` verification and manual `workflow_dispatch` re-verification.
|
||||
- `v0.1.0-alpha.19` exists as a tag, but its Release pipeline failed when the packaged convenience installer's `DEFAULT_RELEASE_TAG` did not match the immutable tag. No GitHub Release was published. The version number is burned and must not be moved, deleted, recreated, or reused.
|
||||
- `v0.1.0-alpha.20` matches the packaged convenience installer's `DEFAULT_RELEASE_TAG` to the tag being produced, which is the defect that burned `v0.1.0-alpha.19`. It also adds a pipeline step that tests the latest published release before a new one is cut. It carries the content that `v0.1.0-alpha.19` failed to publish: the operator web console, the guided unified installer, the complete uninstall mode, the node enrollment endpoint, and the mesh state permission fix.
|
||||
|
||||
Every release candidate must pass a branch `workflow_dispatch` run of the Release pipeline before its immutable version tag is created. The release owner has sole write ownership of version sources, `deploy/**`, `tests/bootstrap/**`, release workflows, the root README release status, and translated README release statuses. Other contributors request changes to those paths in their report; they do not edit or bump them directly. One pull request covers one release topic and may merge only after required CI is green.
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@
|
|||
- [x] ограниченный offline buffer Agent и downsampling;
|
||||
- [x] idempotency и replay protection;
|
||||
- [x] SQLite schema version, retention и backup/restore Control DB + CA;
|
||||
- [x] веб-консоль оператора на Control: список узлов, состояние агентов и
|
||||
выпуск кода регистрации;
|
||||
- [x] отдача ассетов консоли из встроенных ресурсов сборки, когда каталога
|
||||
`wwwroot` нет на диске;
|
||||
- [x] вход по логину и паролю для тестовых стендов, отключённый по умолчанию;
|
||||
- [ ] добавить Desktop UI управления Automation identities и токенами.
|
||||
|
||||
## Этап 3 — управляемые Links
|
||||
|
|
@ -62,6 +67,12 @@
|
|||
- [x] B-2: независимая фоновая и emergency-triggered реконсиляция, агрегированное состояние недоступного Mesh firewall и Desktop banner;
|
||||
- [x] B-3: факт-первичная реконсиляция использует один `link-list`, удаляет orphan/дубликаты (включая `Disabled/Disabled`), разводит `Examined` / `Converged` / `Failed` (M2), ограничивает marker-prompt тремя попытками, добавляет фильтр истории и retention завершённых Links (M4), а также типизированное ожидание активации Mesh Node (M5). Physical acceptance остаётся внешним блокером;
|
||||
- [ ] выполнить физический acceptance Hub + source Node + два destination Node с WireGuard/nftables/reboot.
|
||||
- [x] управление Links из веб-консоли: создание с подтверждением направления,
|
||||
обязательной причиной и ключом идемпотентности;
|
||||
- [x] аварийное отключение Link из строки таблицы консоли;
|
||||
- [x] раздельное отображение желаемого и фактического состояния Link
|
||||
с признаком рассогласования и последней ошибкой;
|
||||
- [x] журнал событий Control в реальном времени в веб-консоли;
|
||||
|
||||
## Этап 4 — мониторинг и терминал
|
||||
|
||||
|
|
@ -101,6 +112,8 @@
|
|||
- [x] добавить криптографическую подпись compatibility manifest для production release;
|
||||
- [x] проверять Ubuntu 22.04/24.04 и Debian 12/13, `amd64`/`arm64`;
|
||||
- [x] добавить non-interactive install/update/rollback/uninstall;
|
||||
- [x] добавить режим полного удаления сервера;
|
||||
- [x] добавить пошаговый объединённый установщик;
|
||||
- [x] устанавливать Control/Agent, restricted helper и systemd units;
|
||||
- [x] локально создавать Agent key/CSR, выполнять mTLS enrollment и не сохранять token;
|
||||
- [x] добавить собственную установку WireGuard Hub/Node и выдачу внутренних адресов;
|
||||
|
|
|
|||
Loading…
Reference in a new issue