release: bump version to 0.11.5

Replace interim FUTURE_WORK.md with slim STANDARDS.md and update doc links.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
mixeme
2026-07-01 23:16:24 +03:00
parent aed83b91b9
commit 9216f01bf6
7 changed files with 44 additions and 117 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ creating, grouping, pausing, running, and monitoring scheduled shell commands.
- [Changelog](docs/CHANGELOG.md) - [Changelog](docs/CHANGELOG.md)
- [Roadmap](docs/ROADMAP.md) - [Roadmap](docs/ROADMAP.md)
- [Architecture](docs/ARCHITECTURE.md) - [Architecture](docs/ARCHITECTURE.md)
- [Future Work](docs/FUTURE_WORK.md) — quality standard, maturity checklist, open polish - [Standards](docs/STANDARDS.md) — quality rules and intentional behavior
- [Development](docs/DEVELOPMENT.md) — build instructions, project layout, dependencies - [Development](docs/DEVELOPMENT.md) — build instructions, project layout, dependencies
## Storage ## Storage
+1 -2
View File
@@ -156,8 +156,7 @@ counted but the timing is skipped.
`JobRuntime.Logs` (per-run `RunRecord` entries shown in the History tab) is `JobRuntime.Logs` (per-run `RunRecord` entries shown in the History tab) is
**session-only**: it is not written to `jobs.json` and is not rebuilt from **session-only**: it is not written to `jobs.json` and is not rebuilt from
`.log` files on startup. Log files on disk feed aggregate counters via `.log` files on startup. Log files on disk feed aggregate counters via
`SeedStats` only. See [FUTURE_WORK.md](FUTURE_WORK.md) for the intentional `SeedStats` only. See [STANDARDS.md](STANDARDS.md).
trade-off.
### Persisted global pause ### Persisted global pause
+12
View File
@@ -2,6 +2,18 @@
All notable GoSentry changes are recorded in this file. All notable GoSentry changes are recorded in this file.
## 0.11.5 - 2026-07-01
**Quality and documentation polish:**
- Replaced the interim `docs/FUTURE_WORK.md` with `docs/STANDARDS.md` — a slim,
permanent reference for code-quality rules and intentional behavior.
- `newMainView` now accepts an injected `*app.Service` for testability;
`RunNow` errors are shown in a dialog instead of failing silently.
- Empty job lists no longer panic when building the Jobs tab.
- Added regression and helper tests for overlap/pause scheduling, UI history
helpers, main-view smoke build, and Linux desktop integration.
## 0.11.4 - 2026-06-30 ## 0.11.4 - 2026-06-30
**Statistics:** **Statistics:**
-112
View File
@@ -1,112 +0,0 @@
# GoSentry — Future Work
> Временный документ: цель проекта, стандарт качества и открытые задачи.
> После завершения шлифовки переименуем (например, в `STANDARDS.md`).
## Зачем этот документ
**Образцовый проект** — тот, на который можно сослаться как на эталон: архитектура
понятна с первого прочтения, границы пакетов соблюдаются, намеренные компромиссы
задокументированы, поведение воспроизводимо тестами, новый контрибьютор знает
*как* и *почему* писать код здесь.
Оценки зрелости ниже — **зеркало**, не KPI. Поднимать балл ради балла не имеет
смысла; имеет смысл закрывать пункты чеклиста.
## Базовая оценка (внутреннее ревью, 2026-06-29)
| Критерий | Оценка |
|----------|--------|
| Архитектура | 9/10 |
| Сложность vs масштаб | 8/10 |
| Качество кода | 8/10 |
| Поддерживаемость | 8/10 |
| Логические ошибки | 9/10 |
Ревью проводилось на **0.11.2**; исправления вошли в **0.11.30.11.4**.
Текущая версия: `src/app/version.go`.
## Архитектурные сильные стороны
- Single-writer `app.Service` с явным locking contract
- Разделение `domain.Job` (durable) и `domain.JobRuntime` (transient)
- Event-driven UI без обратных вызовов в Fyne под lock
- Portable storage от `os.Executable()`
- Инъекция `runJob` и `scheduler.Clock` в тестах
- Подробная документация (`ARCHITECTURE.md`, inline comments)
## Стандарт качества (обязателен для нового кода)
- Контракты пакетов — [ARCHITECTURE.md](ARCHITECTURE.md)
- User-facing error → `dialog.ShowError` или History event, не silent `return`
- Pure helpers → unit-тест в том же пакете
- Фикс severity ≥ medium → regression-тест
- Намеренное поведение → §«Намеренное поведение» ниже, не backlog-баг
- UI view-конструкторы принимают `*app.Service`, не вызывают `app.Open()` внутри
## Чеклист зрелости
| # | Критерий | Статус |
|---|----------|--------|
| 1 | Контракты пакетов задокументированы и соблюдаются | ✓ |
| 2 | Намеренные trade-off'ы явно записаны | ✓ |
| 3 | Нет silent failures в user-facing путях | ✓ |
| 4 | Pure logic вынесена и покрыта unit-тестами | ✓ |
| 5 | Regression-тест на серьёзные фиксы ревью | ✓ |
| 6 | DI на границе UI↔Service | ✓ |
| 7 | Документация = код | ✓ |
| 8 | Platform-код тестируется по одному образцу | ✓ |
| 9 | Единый стиль ошибок в UI | ✓ |
## Намеренное поведение (не баги)
- `RunNow` разрешён при global pause и для disabled jobs
- Sequential mode — FIFO по порядку в `jobs.json`
- Scheduler tick 1s — sub-second `@every` не поддерживается
- Command timeout 30s — глобальный лимит
- **History tab — session-only.** `JobRuntime.Logs` живёт только в памяти
текущей сессии. Файлы в `logs_dir` используются для aggregate stats
(`SeedStats`), не для таблицы History. Подробнее — [ARCHITECTURE.md](ARCHITECTURE.md).
## Закрытые находки ревью (2026-06-29)
Историческая справка; не открывать повторно без новых данных.
| # | Проблема | Серьёзность | Статус |
|---|----------|-------------|--------|
| 1 | Data race: `store.Paths` в `executeRun` без lock | Высокая | Исправлено |
| 2 | Run стартует при ошибке `SaveJobs` | Средняя | Исправлено |
| 3 | CRUD эмитит events при failed save | Средняя | Исправлено |
| 4 | Overlap queue — только один `Pending` | Средняя | Исправлено (`PendingRuns`) |
| 5 | `time.Now()` vs scheduler clock в `startRunLocked` | Низкая | Исправлено |
| 6 | Silent log write failures | Низкая | Исправлено |
| 7 | Невалидный per-job `overlap_policy` | Низкая | Исправлено |
| 8 | Docs drift (YAML, RunNow/pause) | Низкая | Исправлено |
| 9 | `StartOnly` игнорировал cancel context | Низкая | Исправлено |
| 10 | `SeedStats` коллизия sanitized имён | Низкая | Исправлено (match по `job_id`) |
| 11 | `AvgDurationMS` seed vs live расходились | Низкая | Исправлено (`TimedRunCount`) |
| 12 | Legacy ticket-ссылки в комментариях | Низкая | Исправлено |
## Вне scope (осознанные trade-off'ы)
| Item | Где зафиксировано |
|------|-------------------|
| History из `.log` | Session-only by design (§выше) |
| Per-job command timeout | [ROADMAP.md](ROADMAP.md) |
| Window size persistence | [ROADMAP.md](ROADMAP.md) (frozen) |
| Column filters в History | [ROADMAP.md](ROADMAP.md) |
| CI coverage gate | [ROADMAP.md](ROADMAP.md) (будущее) |
## Честно про 10/10
Единые **10/10** по всем критериям — неразумная цель для Fyne desktop: CGO,
platform stubs и headless-лимиты GUI объективно добавляют сложность.
**Образцовость ≠ идеальный балл.** Целевое состояние: чеклист зрелости ✓,
проект как reference implementation layered Go desktop app.
## Связанные документы
- [ARCHITECTURE.md](ARCHITECTURE.md) — контракты пакетов
- [TESTS.md](TESTS.md) — как и что тестировать
- [ROADMAP.md](ROADMAP.md) — крупные фичи и platform blockers
- [DEVELOPMENT.md](DEVELOPMENT.md) — сборка и layout
+28
View File
@@ -0,0 +1,28 @@
# GoSentry — Standards
Quality rules and intentional behavior for contributors. Package contracts live
in [ARCHITECTURE.md](ARCHITECTURE.md); test conventions in [TESTS.md](TESTS.md).
## Code quality
- Follow package contracts in [ARCHITECTURE.md](ARCHITECTURE.md).
- User-facing errors → `dialog.ShowError` or a History event, never a silent `return`.
- Pure helpers → unit test in the same package.
- Fixes with severity ≥ medium → regression test.
- Documented intentional behavior → section below, not a backlog bug.
- UI view constructors accept `*app.Service`; call `app.Open()` only from `run.go`.
## Intentional behavior (not bugs)
- `RunNow` is allowed during global pause and for disabled jobs.
- Sequential mode runs jobs FIFO by order in `jobs.json`.
- Scheduler tick is 1s — sub-second `@every` intervals are not supported.
- Command timeout is 30s globally.
- **History tab is session-only.** `JobRuntime.Logs` exists only in memory for the
current process. Log files on disk feed aggregate statistics via `SeedStats`
only. See [ARCHITECTURE.md](ARCHITECTURE.md).
## Out of scope
Larger or blocked work is tracked in [ROADMAP.md](ROADMAP.md) (per-job timeout,
window size persistence, History column filters, CI coverage gate).
+1 -1
View File
@@ -412,5 +412,5 @@ Smoke test for main view construction with an injected `*app.Service`.
## Remaining Test Coverage Gaps ## Remaining Test Coverage Gaps
- Full GUI E2E — tab navigation, dialog flows, and native file pickers are not exercised end-to-end - Full GUI E2E — tab navigation, dialog flows, and native file pickers are not exercised end-to-end
- History is session-only by design — `.log` files seed aggregate stats only, not the History table (see [FUTURE_WORK.md](FUTURE_WORK.md)) - History is session-only by design — `.log` files seed aggregate stats only, not the History table (see [STANDARDS.md](STANDARDS.md))
- `layout.go` custom layouts — optional Fyne `test.NewApp()` coverage when CGO is available in CI - `layout.go` custom layouts — optional Fyne `test.NewApp()` coverage when CGO is available in CI
+1 -1
View File
@@ -3,4 +3,4 @@ package app
// Version is the application version shown in the GUI and used by build // Version is the application version shown in the GUI and used by build
// scripts in artifact names. It is a var rather than a const so release builds // scripts in artifact names. It is a var rather than a const so release builds
// can override it with Go ldflags when CI tags a build. // can override it with Go ldflags when CI tags a build.
var Version = "0.11.4" var Version = "0.11.5"