Add an optional per-job run timeout following the overlap_policy inherit
pattern: Job.TimeoutSeconds (0 = inherit) resolves against a new
Config.DefaultTimeoutSeconds (default 30s), replacing the hard-coded 30s
guard in runner.RunJob.
- domain/storage: new fields, default 30, load-time normalization
- runner: RunJob takes an explicit timeout; StartOnly stays untimed so it
keeps measuring launch latency only
- app: effectiveTimeout resolves under mu into runEnv, threaded to runJob;
seam signature and validation updated; DisplayTimeout helper
- ui: Timeout entry in the job dialog, Default timeout in Settings, and a
Timeout row in the details panel
- tests + docs (ARCHITECTURE, STANDARDS, ROADMAP, CHANGELOG) updated;
version bumped to 0.12.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T6.1: split jobs_view.go into three files — jobs_view_helpers.go (pure
helpers) and jobs_view_details.go (detailsPanel struct with widget
creation, update, clear, and container methods) — bringing jobs_view.go
from 459 to ~200 lines.
T6.2: remove stale YAML upgrade note from README; drop *.yaml from
.dockerignore.
T6.3: delete YAML shadow structs (yamlConfig/yamlJob/yamlJobsFile),
importYAMLConfig/importYAMLJobs, legacy path constants, and all
YAML-import tests; run go mod tidy to remove go.yaml.in/yaml/v4.
T6.4: refresh ARCHITECTURE.md — JSON storage references, new Key Domain
Concepts section (per-job overlap policy, run-time statistics + log
seeding, persisted pause flag, jobs_view split).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Config.Paused bool so the scheduler's paused flag survives a restart.
SetGlobalPause now writes the flag into store.Config and calls SaveConfig;
NewService seeds s.paused from Config.Paused before computing first next-run
times, so jobs show "Scheduler paused" immediately at startup when paused.
Also add Paused to the yamlConfig shadow struct to keep the direct conversion
from domain.Config valid until the YAML import path is dropped in T6.3.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds OverlapPolicy field to Job struct with json:"overlap_policy,omitempty"
tag. When empty, the field signals that the job should inherit the global
overlap policy setting from Config. Also updates yamlJob shadow struct to
maintain field-layout equivalence for YAML→JSON import compatibility.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Introduces ExecutionMode (parallel/sequential) and OverlapPolicy
(skip/queue) types and constants in domain/config.go, wires defaults
(parallel/skip) into loadOrCreateConfig and the normalization pass, and
adds validation in validateConfig. Adds Pending bool to JobRuntime as
the flag P3.3 will use to re-run a queued overlap. Marks P3.1 done.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove the SuccessExitCodes field from domain.Job and every layer that
read or wrote it: runner/exitcodes.go (deleted), runner.go runStateDetail
simplified to 0=OK / non-zero=Failed, logfile.go, format.go, operations.go,
store.go, job_dialog.go, and jobs_view.go. Tests updated accordingly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When gosentry.json / jobs.json are absent, read a pre-migration
gosentry.yaml / jobs.yaml via private yaml-tagged shadow structs and
return the data unsaved; the existing SaveConfig/SaveJobs in OpenStore
then rewrite it as JSON. Replaces the placeholder that pointed configPath
at the legacy YAML file and tried to json.Unmarshal it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ConfigFileName → "gosentry.json", JobsFileName → "jobs.json"
- Remove exported LegacyConfigFileName ("pysentry.yaml")
- Add unexported legacyYAMLConfigFileName / legacyYAMLJobsFileName for
the upcoming one-time YAML import (P1.4)
- Update store.go fallback path and comments to describe YAML→JSON
migration rather than the old PySentry→GoSentry rename
- Align store_test.go references and test comments
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace writeYAML with writeJSON (json.MarshalIndent, 2-space indent,
trailing newline) and switch the config and jobs Unmarshal calls to
encoding/json. Mark P1.2 done in the pre-release task list.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
## Summary
Completed Phase 5 refactoring and reached the target architecture.
**Architectural milestone achieved:**
- Service layer owns all state and is the sole writer
- UI is a thin Fyne view, all widget updates marshaled via `fyne.Do`
- Core engines are stateless and injectable
- Domain types are pure (no `yaml:"-"` fields)
- Full module builds and `go vet ./...` clean
## Changes
- Bump version: 0.3.6 → 0.4.0
- Update CHANGELOG with Phase 5 summary
- Add ROADMAP "Refactoring Follow-Ups" section
## Known follow-up work
1. **Linux test build broken** — `runner_test.go` needs `//go:build windows` tag
2. **File-size limits exceeded** — `operations.go` (486 lines), `jobs_view.go` (415 lines)
See ROADMAP.md for details.
---------
Co-authored-by: mixeme <mix.public@ya.ru>
Reviewed-on: #1