feat(discovery): implement job discovery system #77

Merged
fuzzy merged 3 commits from feature/0014-implement-job-discovery into main 2026-07-05 13:48:31 +00:00
Owner

What

Implement job discovery: scan interval directories, detect job type (ephemeral vs recurring), parse numeric IDs, and load job configs with defaults.

Why

Enables the discovery layer that feeds into the job execution engine.

Testing

  • 24 unit tests pass
  • Pre-commit hooks pass (ruff, mypy, formatting)
  • Coverage: config 100%, discovery 100%

Breaking Changes

None.

Notes

Job type determined by marker files: .ephemeral = run-once/delete, .recurring (or absent) = keep after run. Non-numeric directories are skipped with a warning.

Closes #0010
Closes #0011
Closes #0012
Closes #0013
Closes #0014

## What Implement job discovery: scan interval directories, detect job type (ephemeral vs recurring), parse numeric IDs, and load job configs with defaults. ## Why Enables the discovery layer that feeds into the job execution engine. ## Testing - [x] 24 unit tests pass - [x] Pre-commit hooks pass (ruff, mypy, formatting) - [x] Coverage: config 100%, discovery 100% ## Breaking Changes None. ## Notes Job type determined by marker files: `.ephemeral` = run-once/delete, `.recurring` (or absent) = keep after run. Non-numeric directories are skipped with a warning. Closes #0010 Closes #0011 Closes #0012 Closes #0013 Closes #0014
- discover_jobs: orchestrate scanning, type detection, config loading
- scan_intervals: find hourly/daily/weekly/monthly dirs with job IDs
- detect_job_type: marker files (.ephemeral / .recurring) for lifecycle
- parse_job_id: extract numeric ID from directory name
- load_job_config: read job config.toml with default fallback
Closes #0010
Closes #0011
Closes #0012
Closes #0013
Cover interval scanning, ID parsing, type detection, config loading,
full discovery, and error cases.
docs: mark Phase 1 Task 3 complete
All checks were successful
CI / lint (pull_request) Successful in 1m26s
CI / test (pull_request) Successful in 49s
9924805d86
Job discovery with interval scanning, type detection, ID parsing,
and default config handling done.
Closes #0014
the.auditor left a comment

Automated Review — PR #77

Result: APPROVED


Clean implementation of the discovery layer. Here's the analysis:

  • Correctness: Directory structure scanning, ID parsing, type detection, and config loading all work as described. Non-numeric directories are skipped with a warning. Missing config falls back to defaults. Marker file detection is clear.
  • Completeness: Closes #10–#14. ROADMAP updated.
  • Test coverage: 24 tests, well-organized into test classes, 100% discovery module coverage. Tests cover empty intervals, unknown folders, non-numeric dirs, marker files, partial config, and error paths.
  • Error handling: DiscoveryError for missing jobs directory. ValueError from parse_job_id caught per-job with warning. ConfigError from invalid config.toml propagates up (see suggestion #3).
  • Maintainability: Clean code, constants at module level, good separation of concerns between scan/parse/detect/load.

Suggestions (non-blocking)

  1. src/kronai/discovery.py:66-70except ValueError wraps three function calls but only parse_job_id raises it. Consider narrowing the try/except to just the parse_job_id() call to avoid silently swallowing future ValueError from other functions:

    try:
        job_id = parse_job_id(job_path)
    except ValueError:
        logger.warning("Skipping non-numeric directory: %s", job_path)
        continue
    job_type = detect_job_type(job_path)
    config = load_job_config(job_path)
    
  2. src/kronai/discovery.py:130-137raw.get() returns object but values flow into typed JobConfig() fields. e.g., mcp_servers expects list[str] but a TOML table or scalar would slip through silently. Consider adding isinstance guards or using a Pydantic-style validator in the future.

  3. src/kronai/discovery.py — Invalid config.toml raises ConfigError which propagates from discover_jobs() and halts discovery of all jobs. Consider catching it per-job (log warning, use defaults) so one bad config doesn't block everything.

## Automated Review — PR #77 **Result: APPROVED** --- Clean implementation of the discovery layer. Here's the analysis: - **Correctness**: Directory structure scanning, ID parsing, type detection, and config loading all work as described. Non-numeric directories are skipped with a warning. Missing config falls back to defaults. Marker file detection is clear. - **Completeness**: Closes #10–#14. ROADMAP updated. - **Test coverage**: 24 tests, well-organized into test classes, 100% discovery module coverage. Tests cover empty intervals, unknown folders, non-numeric dirs, marker files, partial config, and error paths. - **Error handling**: `DiscoveryError` for missing jobs directory. `ValueError` from `parse_job_id` caught per-job with warning. `ConfigError` from invalid config.toml propagates up (see suggestion #3). - **Maintainability**: Clean code, constants at module level, good separation of concerns between scan/parse/detect/load. ### Suggestions (non-blocking) 1. **`src/kronai/discovery.py:66-70`** — `except ValueError` wraps three function calls but only `parse_job_id` raises it. Consider narrowing the try/except to just the `parse_job_id()` call to avoid silently swallowing future `ValueError` from other functions: ```python try: job_id = parse_job_id(job_path) except ValueError: logger.warning("Skipping non-numeric directory: %s", job_path) continue job_type = detect_job_type(job_path) config = load_job_config(job_path) ``` 2. **`src/kronai/discovery.py:130-137`** — `raw.get()` returns `object` but values flow into typed `JobConfig()` fields. e.g., `mcp_servers` expects `list[str]` but a TOML table or scalar would slip through silently. Consider adding `isinstance` guards or using a Pydantic-style validator in the future. 3. **`src/kronai/discovery.py`** — Invalid `config.toml` raises `ConfigError` which propagates from `discover_jobs()` and halts discovery of all jobs. Consider catching it per-job (log warning, use defaults) so one bad config doesn't block everything.
fuzzy merged commit 9924805d86 into main 2026-07-05 13:48:31 +00:00
fuzzy deleted branch feature/0014-implement-job-discovery 2026-07-05 13:48:31 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
thwap/kronai!77
No description provided.