job-workflow 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.agents/instructions/coding-style.md +38 -0
- data/.agents/instructions/domain.md +37 -0
- data/.agents/instructions/environment.md +44 -0
- data/.agents/instructions/general.md +29 -0
- data/.agents/instructions/security.md +20 -0
- data/.agents/instructions/structure.md +43 -0
- data/.agents/instructions/tech-stack.md +40 -0
- data/.agents/instructions/testing.md +46 -0
- data/.agents/instructions/workflow.md +39 -0
- data/.rubocop.yml +1 -2
- data/AGENTS.md +23 -0
- data/CHANGELOG.md +26 -0
- data/README.md +1 -1
- data/app/controllers/job_workflow/monitoring/application_controller.rb +11 -0
- data/app/controllers/job_workflow/monitoring/executions_controller.rb +28 -0
- data/app/controllers/job_workflow/monitoring/workflows_controller.rb +11 -0
- data/app/views/job_workflow/monitoring/executions/index.html.erb +57 -0
- data/app/views/job_workflow/monitoring/executions/show.html.erb +200 -0
- data/app/views/job_workflow/monitoring/workflows/index.html.erb +39 -0
- data/app/views/layouts/job_workflow/monitoring/application.html.erb +117 -0
- data/config/routes.rb +8 -0
- data/guides/API_REFERENCE.md +9 -6
- data/guides/DEPENDENCY_WAIT.md +9 -5
- data/guides/MONITORING_UI.md +74 -0
- data/guides/PARALLEL_PROCESSING.md +33 -21
- data/guides/PRODUCTION_DEPLOYMENT.md +1 -1
- data/guides/README.md +6 -1
- data/guides/THROTTLING.md +24 -0
- data/guides/WORKFLOW_STATUS_QUERY.md +7 -1
- data/lib/job_workflow/context.rb +7 -5
- data/lib/job_workflow/dsl.rb +0 -4
- data/lib/job_workflow/instrumentation/opentelemetry_subscriber.rb +1 -1
- data/lib/job_workflow/instrumentation.rb +14 -14
- data/lib/job_workflow/job_status.rb +16 -1
- data/lib/job_workflow/monitoring/dag_layout.rb +186 -0
- data/lib/job_workflow/monitoring/engine.rb +15 -0
- data/lib/job_workflow/monitoring/execution_page.rb +16 -0
- data/lib/job_workflow/monitoring/execution_registry.rb +50 -0
- data/lib/job_workflow/monitoring/execution_view_model.rb +258 -0
- data/lib/job_workflow/monitoring/parameter_filter.rb +37 -0
- data/lib/job_workflow/monitoring/workflow_definition.rb +24 -0
- data/lib/job_workflow/monitoring/workflow_registry.rb +24 -0
- data/lib/job_workflow/monitoring.rb +120 -0
- data/lib/job_workflow/queue_adapters/abstract.rb +7 -2
- data/lib/job_workflow/queue_adapters/null_adapter.rb +12 -1
- data/lib/job_workflow/queue_adapters/solid_queue_adapter.rb +42 -12
- data/lib/job_workflow/railtie.rb +2 -0
- data/lib/job_workflow/runner.rb +5 -3
- data/lib/job_workflow/sub_task_job.rb +93 -0
- data/lib/job_workflow/task_enqueue.rb +19 -12
- data/lib/job_workflow/version.rb +1 -1
- data/lib/job_workflow/workflow_status.rb +39 -3
- data/lib/job_workflow.rb +2 -0
- data/rbs_collection.lock.yaml +11 -11
- data/sig/generated/job_workflow/context.rbs +7 -7
- data/sig/generated/job_workflow/instrumentation/opentelemetry_subscriber.rbs +0 -1
- data/sig/generated/job_workflow/instrumentation.rbs +28 -28
- data/sig/generated/job_workflow/job_status.rbs +5 -2
- data/sig/generated/job_workflow/monitoring/dag_layout.rbs +80 -0
- data/sig/generated/job_workflow/monitoring/engine.rbs +8 -0
- data/sig/generated/job_workflow/monitoring/execution_page.rbs +14 -0
- data/sig/generated/job_workflow/monitoring/execution_registry.rbs +21 -0
- data/sig/generated/job_workflow/monitoring/execution_view_model.rbs +111 -0
- data/sig/generated/job_workflow/monitoring/parameter_filter.rbs +16 -0
- data/sig/generated/job_workflow/monitoring/workflow_definition.rbs +18 -0
- data/sig/generated/job_workflow/monitoring/workflow_registry.rbs +13 -0
- data/sig/generated/job_workflow/monitoring.rbs +38 -0
- data/sig/generated/job_workflow/queue_adapters/abstract.rbs +7 -4
- data/sig/generated/job_workflow/queue_adapters/null_adapter.rbs +5 -2
- data/sig/generated/job_workflow/queue_adapters/solid_queue_adapter.rbs +18 -6
- data/sig/generated/job_workflow/runner.rbs +1 -1
- data/sig/generated/job_workflow/sub_task_job.rbs +40 -0
- data/sig/generated/job_workflow/task_enqueue.rbs +5 -8
- data/sig/generated/job_workflow/workflow_status.rbs +18 -2
- data/sig-private/job-workflow.rbs +11 -0
- data/sig-private/rails.rbs +5 -0
- metadata +42 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '08ad79c285a78a258aaafdf2cca6141982291f52c00a7c95412a7df728f96217'
|
|
4
|
+
data.tar.gz: 4fba62aa4a507ab75f8fb33ac21b1fadaa409452f985be9e1eedff0a010a3614
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5b079b1bb1b534b9952de0b431d6fac1658e9581ea30d22cbe5b0737e7c7748f78af68a46880500d8c3da9edc51bf5b4e558adf568ae1f0ce014cf77bd336ab8
|
|
7
|
+
data.tar.gz: fc2a98038a737cd4bc47c4f029bc2df17d55ec6d2ce16ca031f14a84cce8ac5a9418f20b18fc8174a2e157b74488557e4335bbed9afe71582141adc97ea28a00
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Coding Style
|
|
2
|
+
|
|
3
|
+
## Primary sources of truth
|
|
4
|
+
|
|
5
|
+
- `.rubocop.yml` for Ruby style, complexity, and naming constraints
|
|
6
|
+
- `Steepfile`, `rbs_collection.yaml`, and inline RBS usage for type-checking expectations
|
|
7
|
+
- `.github/copilot-instructions.md` for repository-specific design and testing rules
|
|
8
|
+
|
|
9
|
+
## Mechanical style constraints
|
|
10
|
+
|
|
11
|
+
- Ruby string literals use double quotes.
|
|
12
|
+
- RuboCop line length is capped at 120 characters.
|
|
13
|
+
- The repository excludes `examples/**/*` from the root RuboCop config because the example app validates itself separately.
|
|
14
|
+
|
|
15
|
+
## Design rules
|
|
16
|
+
|
|
17
|
+
- Keep code small and focused on a single responsibility.
|
|
18
|
+
- Prefer composable behavior over large monolithic methods.
|
|
19
|
+
- Favor immutable workflow inputs through `Arguments`.
|
|
20
|
+
- Use `Output` as the main way to communicate task side effects and downstream data.
|
|
21
|
+
- Preserve clear boundaries between `Workflow`, `Task`, and `Runner`.
|
|
22
|
+
- Avoid breaking public APIs without a documented migration or deprecation path.
|
|
23
|
+
|
|
24
|
+
## Type and signature rules
|
|
25
|
+
|
|
26
|
+
- Prefer `rbs-inline` comments in implementation files when type information changes.
|
|
27
|
+
- Do not edit generated `.rbs` files or `sig/` artifacts directly unless maintainers explicitly approve it.
|
|
28
|
+
|
|
29
|
+
## Test-adjacent implementation rules
|
|
30
|
+
|
|
31
|
+
- Add only the code necessary for the requested behavior and its directly related fixes.
|
|
32
|
+
- Reuse existing helpers and patterns before adding new abstractions.
|
|
33
|
+
- Comment code only when the behavior is non-obvious.
|
|
34
|
+
- Do not change established naming conventions without approval.
|
|
35
|
+
|
|
36
|
+
## Unconfirmed items
|
|
37
|
+
|
|
38
|
+
- Any additional hand-written naming rules beyond Ruby conventions and RuboCop enforcement
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Domain
|
|
2
|
+
|
|
3
|
+
## Repository purpose
|
|
4
|
+
|
|
5
|
+
JobWorkflow is a workflow orchestration library for Ruby on Rails applications. It provides a declarative DSL on top of ActiveJob so applications can define task graphs, dependencies, fan-out work, retries, throttling, and monitoring.
|
|
6
|
+
|
|
7
|
+
## Core concepts
|
|
8
|
+
|
|
9
|
+
- `Workflow`: the ordered graph of tasks for a job class
|
|
10
|
+
- `Task`: one unit of work in a workflow, optionally depending on other tasks
|
|
11
|
+
- `Arguments`: immutable workflow inputs exposed to tasks through `Context`
|
|
12
|
+
- `Context`: the task-facing object used to read arguments, outputs, runtime helpers, and execution state
|
|
13
|
+
- `Output`: the structured result store for completed task outputs
|
|
14
|
+
- `Runner`: the orchestration layer that executes tasks and updates workflow state
|
|
15
|
+
- `SubTaskJob`: the dedicated async job class used for `enqueue: true` fan-out work
|
|
16
|
+
- `WorkflowStatus` / `JobStatus`: read models for workflow and sub-task execution state
|
|
17
|
+
- Monitoring UI: the Rails engine that visualizes workflow definitions and execution DAGs
|
|
18
|
+
|
|
19
|
+
## Common terminology
|
|
20
|
+
|
|
21
|
+
- `each task`: a task that fans out over a collection
|
|
22
|
+
- `dependency_wait`: waiting behavior for dependent async work
|
|
23
|
+
- `fan-out`: splitting work into sub-jobs
|
|
24
|
+
- `root execution`: the top-level workflow job, excluding sub-task jobs
|
|
25
|
+
|
|
26
|
+
## Detailed references
|
|
27
|
+
|
|
28
|
+
- `guides/GETTING_STARTED.md` for the high-level workflow model
|
|
29
|
+
- `guides/DSL_BASICS.md` for task definitions and dependency rules
|
|
30
|
+
- `guides/TASK_OUTPUTS.md` for output flow and downstream consumption
|
|
31
|
+
- `guides/PARALLEL_PROCESSING.md` for fan-out and aggregation behavior
|
|
32
|
+
- `guides/WORKFLOW_STATUS_QUERY.md` for workflow vs job status read models
|
|
33
|
+
- `guides/MONITORING_UI.md` for the monitoring view of root executions and sub-task jobs
|
|
34
|
+
|
|
35
|
+
## Unconfirmed items
|
|
36
|
+
|
|
37
|
+
- Additional external domain vocabulary used by downstream adopters
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Environment
|
|
2
|
+
|
|
3
|
+
## Required local tools
|
|
4
|
+
|
|
5
|
+
- Ruby and Bundler for gem development
|
|
6
|
+
- SQLite3 for local development and the example app
|
|
7
|
+
- A shell environment that can run the root and example-app Rake tasks
|
|
8
|
+
|
|
9
|
+
## Root setup
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bin/setup
|
|
13
|
+
bundle install
|
|
14
|
+
bundle exec rake rbs:install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Example app setup
|
|
18
|
+
|
|
19
|
+
From `examples/rails_8_1/`:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bundle install
|
|
23
|
+
bundle exec rails db:prepare
|
|
24
|
+
bundle exec rake rbs:install
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Running the example app
|
|
28
|
+
|
|
29
|
+
- Start the Rails server from `examples/rails_8_1/` with `bin/rails server`
|
|
30
|
+
- Start background job processing with `bin/jobs`
|
|
31
|
+
- Open `/job_workflow` for the monitoring UI and `/jobs` for Mission Control Jobs in the example app
|
|
32
|
+
- For a denser monitoring DAG preview, enqueue `AcceptanceComplexMonitoringDagJob` from `examples/rails_8_1/`
|
|
33
|
+
|
|
34
|
+
## Useful notes
|
|
35
|
+
|
|
36
|
+
- The example app is the main place to verify real monitoring UI behavior.
|
|
37
|
+
- The example app has its own lockfile and validation commands; treat it as an additional maintained surface.
|
|
38
|
+
- Use `examples/rails_8_1/README.md` for the full preview sequence.
|
|
39
|
+
- Use `guides/GETTING_STARTED.md` for first-time library setup and `guides/MONITORING_UI.md` for monitoring behavior.
|
|
40
|
+
|
|
41
|
+
## Unconfirmed items
|
|
42
|
+
|
|
43
|
+
- Preferred Ruby version manager for maintainers
|
|
44
|
+
- Any editor or shell configuration the team expects
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# General
|
|
2
|
+
|
|
3
|
+
## Core behavior
|
|
4
|
+
|
|
5
|
+
- Respond to repository collaborators in Japanese, even though these agent resource files are written in English.
|
|
6
|
+
- Interpret user instructions literally and keep changes scoped to the requested task.
|
|
7
|
+
- Ask for clarification before making risky, ambiguous, or behavior-changing edits.
|
|
8
|
+
- Prefer existing repository conventions over personal defaults.
|
|
9
|
+
|
|
10
|
+
## Always do
|
|
11
|
+
|
|
12
|
+
- Read the relevant repository context before editing.
|
|
13
|
+
- Keep changes focused and avoid unrelated cleanup.
|
|
14
|
+
- Report what changed, what was validated, and any unresolved points when finishing work.
|
|
15
|
+
|
|
16
|
+
## Do not do
|
|
17
|
+
|
|
18
|
+
- Do not create unrelated refactors while working on a user request.
|
|
19
|
+
- Do not assume undocumented behavior when repository sources do not confirm it.
|
|
20
|
+
- Do not treat generated signatures in `sig/generated/` as the primary editing surface.
|
|
21
|
+
|
|
22
|
+
## Communication
|
|
23
|
+
|
|
24
|
+
- Use concise Japanese in user-facing chat.
|
|
25
|
+
- State uncertainty explicitly instead of presenting guesses as facts.
|
|
26
|
+
|
|
27
|
+
## Unconfirmed items
|
|
28
|
+
|
|
29
|
+
- Additional organization-wide communication rules beyond this repository
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Security
|
|
2
|
+
|
|
3
|
+
## Secrets and sensitive data
|
|
4
|
+
|
|
5
|
+
- Do not commit API keys, tokens, passwords, private keys, or other secrets.
|
|
6
|
+
- Stop and ask if a value looks like a secret or production credential.
|
|
7
|
+
|
|
8
|
+
## Restricted operations
|
|
9
|
+
|
|
10
|
+
- Do not modify files outside the repository root.
|
|
11
|
+
|
|
12
|
+
## Dependency and code safety
|
|
13
|
+
|
|
14
|
+
- Prefer existing repository dependencies and tools over introducing new ones.
|
|
15
|
+
- Avoid risky shell operations, destructive git commands, and history rewriting unless explicitly requested.
|
|
16
|
+
- Surface errors instead of silently swallowing them.
|
|
17
|
+
|
|
18
|
+
## Unconfirmed items
|
|
19
|
+
|
|
20
|
+
- External secret-management system used by maintainers
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Structure
|
|
2
|
+
|
|
3
|
+
## Repository layout
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
.
|
|
7
|
+
├── app/ # Rails engine assets for the monitoring UI
|
|
8
|
+
├── bin/ # executable helpers
|
|
9
|
+
├── config/ # Rails engine and routing configuration
|
|
10
|
+
├── examples/rails_8_1/ # acceptance Rails application used to verify integration
|
|
11
|
+
├── guides/ # user-facing documentation
|
|
12
|
+
├── lib/ # main JobWorkflow library code
|
|
13
|
+
├── sig/ # generated signatures and type artifacts
|
|
14
|
+
├── sig-private/ # private type definitions used by Steep
|
|
15
|
+
├── spec/ # main RSpec suite
|
|
16
|
+
├── .agents/instructions/ # agent instructions files referenced from AGENTS.md
|
|
17
|
+
└── AGENTS.md # root agent entry point
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Key areas
|
|
21
|
+
|
|
22
|
+
- `lib/job_workflow/` holds the core DSL, runtime, adapters, monitoring models, and version file.
|
|
23
|
+
- `lib/job_workflow/monitoring/` contains monitoring presenters, registries, and layout helpers.
|
|
24
|
+
- `app/` and `config/routes.rb` support the monitoring UI engine.
|
|
25
|
+
- `examples/rails_8_1/` is a separate validation surface with its own Rake tasks, lockfile, and specs.
|
|
26
|
+
- `examples/rails_8_1/app/jobs/` contains acceptance workflow definitions.
|
|
27
|
+
- `examples/rails_8_1/spec/jobs/` contains acceptance and integration-oriented example-app specs.
|
|
28
|
+
- `guides/` is the documentation index for feature and operational guides.
|
|
29
|
+
|
|
30
|
+
## Structure expectations
|
|
31
|
+
|
|
32
|
+
- Treat this repository as a single package with an embedded example application, not as a monorepo of independent packages.
|
|
33
|
+
- Keep agent-wide documentation at the root unless a future task explicitly introduces subdirectory-specific AGENTS.md files.
|
|
34
|
+
|
|
35
|
+
## Documentation entry points
|
|
36
|
+
|
|
37
|
+
- Start with `guides/README.md` to find the right feature guide.
|
|
38
|
+
- Use `guides/MONITORING_UI.md` for monitoring-specific behavior.
|
|
39
|
+
- Use `examples/rails_8_1/README.md` for example-app setup and preview flows.
|
|
40
|
+
|
|
41
|
+
## Unconfirmed items
|
|
42
|
+
|
|
43
|
+
- Whether additional future example applications should get their own AGENTS.md
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Tech Stack
|
|
2
|
+
|
|
3
|
+
## Languages and frameworks
|
|
4
|
+
|
|
5
|
+
- Ruby `>= 3.1.0` for the gem runtime
|
|
6
|
+
- Rails and ActiveJob for the workflow runtime and monitoring engine integration
|
|
7
|
+
- Solid Queue in the example app for asynchronous execution scenarios
|
|
8
|
+
- SQLite in local and example-app development flows
|
|
9
|
+
- RBS Inline plus Steep for type checking
|
|
10
|
+
- RSpec for tests
|
|
11
|
+
- RuboCop with repository plugins for linting
|
|
12
|
+
- SimpleCov for 100% line and branch coverage enforcement
|
|
13
|
+
|
|
14
|
+
## Primary commands
|
|
15
|
+
|
|
16
|
+
- Root validation:
|
|
17
|
+
- `bundle exec rake spec`
|
|
18
|
+
- `bundle exec rake lint`
|
|
19
|
+
- `bundle exec rake typecheck`
|
|
20
|
+
- Useful root helpers:
|
|
21
|
+
- `bundle exec rake lint:fix`
|
|
22
|
+
- `bundle exec rake lint:fixall`
|
|
23
|
+
- `bundle exec rake rbs:install`
|
|
24
|
+
- `bundle exec rake rbs:update`
|
|
25
|
+
- `bundle exec rake rbs:inline`
|
|
26
|
+
- Example app validation from `examples/rails_8_1/`:
|
|
27
|
+
- `bundle exec rake spec`
|
|
28
|
+
- `bundle exec rake lint`
|
|
29
|
+
- `bundle exec rake typecheck`
|
|
30
|
+
|
|
31
|
+
## Architecture summary
|
|
32
|
+
|
|
33
|
+
- `Workflow`, `Task`, `Runner`, `Arguments`, `Context`, and `Output` form the core execution model.
|
|
34
|
+
- Queue adapters isolate runtime-specific job lookup and persistence behavior.
|
|
35
|
+
- Monitoring code lives under `lib/job_workflow/monitoring/` and is rendered through the Rails engine in `app/`.
|
|
36
|
+
- The example Rails app is the main integration harness for real ActiveJob and Solid Queue behavior.
|
|
37
|
+
|
|
38
|
+
## Important command rule
|
|
39
|
+
|
|
40
|
+
- Use the repository Rake tasks instead of calling `rspec`, `rubocop`, or `steep` directly for final validation.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
## Required validation
|
|
4
|
+
|
|
5
|
+
- Every functional change must include new or updated specs that cover the changed behavior.
|
|
6
|
+
- Root repository changes must pass:
|
|
7
|
+
- `bundle exec rake spec`
|
|
8
|
+
- `bundle exec rake lint`
|
|
9
|
+
- `bundle exec rake typecheck`
|
|
10
|
+
- Root coverage must remain at `100%` line coverage and `100%` branch coverage.
|
|
11
|
+
|
|
12
|
+
## Example app validation
|
|
13
|
+
|
|
14
|
+
- If a change touches `examples/rails_8_1/`, also run inside that directory:
|
|
15
|
+
- `bundle exec rake spec`
|
|
16
|
+
- `bundle exec rake lint`
|
|
17
|
+
- `bundle exec rake typecheck`
|
|
18
|
+
- Example app coverage must also stay at `100%` line coverage and `100%` branch coverage.
|
|
19
|
+
|
|
20
|
+
## Validation scope
|
|
21
|
+
|
|
22
|
+
- If the change only touches root library, engine, guides, or specs outside `examples/rails_8_1/`, run the root validation set.
|
|
23
|
+
- If the change touches both root code and `examples/rails_8_1/`, run both validation sets.
|
|
24
|
+
- If the change alters behavior, update the relevant guide examples as well as tests.
|
|
25
|
+
|
|
26
|
+
## Test-writing rules
|
|
27
|
+
|
|
28
|
+
- Use `bundle exec rake spec`, not `bundle exec rspec`.
|
|
29
|
+
- Define a named subject with `subject(:name)`.
|
|
30
|
+
- Keep `describe` / `context` nesting at three levels or fewer.
|
|
31
|
+
- Prefer one expectation per example unless a matcher like `have_attributes` or a combined matcher makes the assertion a single behavior check.
|
|
32
|
+
- Test through public APIs only; do not use `instance_variable_set`, `instance_variable_get`, or similar reflection in specs.
|
|
33
|
+
- Keep `let` usage lean and split contexts when conditions differ.
|
|
34
|
+
|
|
35
|
+
## Completion rule
|
|
36
|
+
|
|
37
|
+
- Do not report a code change as ready until the required validation commands for the touched surfaces have succeeded.
|
|
38
|
+
|
|
39
|
+
## Reference material
|
|
40
|
+
|
|
41
|
+
- Use `guides/TESTING_STRATEGY.md` for testing guidance beyond the mandatory checks.
|
|
42
|
+
- Use `guides/MONITORING_UI.md` and feature-specific guides when behavior-oriented expectations need clarification.
|
|
43
|
+
|
|
44
|
+
## Unconfirmed items
|
|
45
|
+
|
|
46
|
+
- Whether any additional external CI jobs run outside the repository-local Rake tasks
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Workflow
|
|
2
|
+
|
|
3
|
+
## Branches
|
|
4
|
+
|
|
5
|
+
- Use a dedicated branch for work.
|
|
6
|
+
- Preferred branch prefixes are `feature/<short-desc>` and `fix/<short-desc>`.
|
|
7
|
+
|
|
8
|
+
## Commits
|
|
9
|
+
|
|
10
|
+
- Use Conventional Commits in `type(scope): short summary` format.
|
|
11
|
+
- Valid types include `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, and `perf`.
|
|
12
|
+
- Keep the subject line within 72 characters.
|
|
13
|
+
- Update `CHANGELOG.md` before creating a commit when the change should be reflected in release notes.
|
|
14
|
+
|
|
15
|
+
## Pull requests
|
|
16
|
+
|
|
17
|
+
- Keep one PR focused on one logical change.
|
|
18
|
+
- PR creation and merge are normally done by the user unless they explicitly delegate that step.
|
|
19
|
+
- A completion handoff should include validation results, coverage, lint status, typecheck status, major changed files, and any recommended follow-up.
|
|
20
|
+
|
|
21
|
+
## Before changing behavior
|
|
22
|
+
|
|
23
|
+
- Check `guides/README.md` first to find the relevant feature guide.
|
|
24
|
+
- Use feature guides such as `guides/DSL_BASICS.md`, `guides/TASK_OUTPUTS.md`, `guides/PARALLEL_PROCESSING.md`, `guides/DEPENDENCY_WAIT.md`, and `guides/MONITORING_UI.md` before changing semantics in those areas.
|
|
25
|
+
|
|
26
|
+
## Release preparation
|
|
27
|
+
|
|
28
|
+
- Record shipped changes in `CHANGELOG.md`, starting from `## [Unreleased]` before they are cut into a release section.
|
|
29
|
+
- Keep version-related files in sync when preparing a release.
|
|
30
|
+
|
|
31
|
+
## Review expectations
|
|
32
|
+
|
|
33
|
+
- Explain why a change is necessary.
|
|
34
|
+
- Keep PRs small enough to review without mixing unrelated work.
|
|
35
|
+
|
|
36
|
+
## Unconfirmed items
|
|
37
|
+
|
|
38
|
+
- Reviewer assignment rules outside the repository instructions
|
|
39
|
+
- Whether release tagging always happens from `main`
|
data/.rubocop.yml
CHANGED
|
@@ -41,7 +41,7 @@ Metrics/BlockLength:
|
|
|
41
41
|
Metrics/ClassLength:
|
|
42
42
|
Enabled: true
|
|
43
43
|
CountComments: false
|
|
44
|
-
Max:
|
|
44
|
+
Max: 124
|
|
45
45
|
CountAsOne:
|
|
46
46
|
- array
|
|
47
47
|
- hash
|
|
@@ -88,4 +88,3 @@ Style/StringLiteralsInInterpolation:
|
|
|
88
88
|
|
|
89
89
|
ThreadSafety/ClassAndModuleAttributes:
|
|
90
90
|
Enabled: false
|
|
91
|
-
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This repository uses AGENTS.md as a thin hub. Read the required instructions files before making changes.
|
|
4
|
+
|
|
5
|
+
## Required instructions
|
|
6
|
+
|
|
7
|
+
- @.agents/instructions/general.md
|
|
8
|
+
- @.agents/instructions/structure.md
|
|
9
|
+
- @.agents/instructions/tech-stack.md
|
|
10
|
+
- @.agents/instructions/security.md
|
|
11
|
+
- @.agents/instructions/testing.md
|
|
12
|
+
- @.agents/instructions/workflow.md
|
|
13
|
+
|
|
14
|
+
## Load when needed
|
|
15
|
+
|
|
16
|
+
- .agents/instructions/domain.md — JobWorkflow concepts and terminology
|
|
17
|
+
- .agents/instructions/environment.md — local setup and example app workflow
|
|
18
|
+
- .agents/instructions/coding-style.md — design rules, style constraints, and implementation patterns
|
|
19
|
+
|
|
20
|
+
## Repository notes
|
|
21
|
+
|
|
22
|
+
- Repository-specific reusable agent assets should live under `.agents/skills/`.
|
|
23
|
+
- No subdirectory-level AGENTS.md files are defined at the moment. Use this root entry point unless a later task adds a more specific AGENTS.md.
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.6.1] - 2026-06-01
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Fix monitoring UI task state rendering so tasks recorded as completed in ActiveJob continuation data no longer appear as `pending` when they have no outputs or sub-task statuses
|
|
8
|
+
|
|
9
|
+
## [0.6.0] - 2026-05-24
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Add `JobWorkflow::SubTaskJob` for `enqueue: true` task fan-out so each-task sub-jobs run on a dedicated job class instead of reusing the workflow DSL job class directly
|
|
14
|
+
- Add a JobWorkflow monitoring UI engine with an execution DAG overview for browsing workflow definitions, root executions, DAG state, arguments, outputs, fan-out progress, and linked Mission Control Jobs rows
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Breaking:** `WorkflowStatus.find` / `find_by` are now root-workflow-only APIs. Sub-task job IDs are excluded and should be tracked via `JobStatus`.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Route enqueued each-task execution through `SubTaskJob`, restoring workflow/task context from the parent workflow job and keeping parent/sub-job identity separate during async execution
|
|
23
|
+
- Extend queue-adapter and workflow-status hydration so monitoring can paginate root workflow executions, hydrate sub-task detail on demand, and keep partially completed fan-out tasks visible as `running` until the workflow actually settles
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
|
|
27
|
+
- Remove `enqueue: { concurrency: N }`. Async map task fan-out is still controlled by `enqueue`, but execution caps are now configured exclusively with `throttle`.
|
|
28
|
+
|
|
3
29
|
## [0.5.0] - 2026-05-13
|
|
4
30
|
|
|
5
31
|
### Added
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# JobWorkflow
|
|
2
2
|
|
|
3
|
-
> ⚠️ **Early Stage (v0.
|
|
3
|
+
> ⚠️ **Early Stage (v0.6.1):** This library is in active development. APIs and features may change in breaking ways without notice. Use in production at your own risk and expect potential breaking changes in future releases.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JobWorkflow
|
|
4
|
+
module Monitoring
|
|
5
|
+
# Resolve the host app controller at load time so engine controllers inherit
|
|
6
|
+
# the app's existing authentication and access control hooks.
|
|
7
|
+
class ApplicationController < JobWorkflow::Monitoring.resolved_base_controller_class.constantize
|
|
8
|
+
layout "job_workflow/monitoring/application"
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JobWorkflow
|
|
4
|
+
module Monitoring
|
|
5
|
+
class ExecutionsController < ApplicationController
|
|
6
|
+
def index
|
|
7
|
+
@workflow = WorkflowRegistry.find(params[:workflow_job_class_name])
|
|
8
|
+
return render plain: "Workflow definition not found.", status: :not_found if @workflow.nil?
|
|
9
|
+
|
|
10
|
+
@page = ExecutionRegistry.page_for(
|
|
11
|
+
job_class_name: @workflow.name,
|
|
12
|
+
cursor: params[:cursor]
|
|
13
|
+
)
|
|
14
|
+
@executions = @page.executions
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def show
|
|
18
|
+
@workflow = WorkflowRegistry.find(params[:workflow_job_class_name])
|
|
19
|
+
return render plain: "Workflow definition not found.", status: :not_found if @workflow.nil?
|
|
20
|
+
|
|
21
|
+
@execution = ExecutionRegistry.find(params[:id])
|
|
22
|
+
return if @execution && @execution.job_class_name == @workflow.name
|
|
23
|
+
|
|
24
|
+
render plain: "Workflow execution is no longer available.", status: :not_found
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<section class="d-flex flex-column flex-lg-row justify-content-between align-items-lg-end gap-3 mb-4">
|
|
2
|
+
<div>
|
|
3
|
+
<div class="text-body-secondary small mb-1">Workflow</div>
|
|
4
|
+
<h1 class="display-6 fw-semibold mb-2"><%= @workflow.name %></h1>
|
|
5
|
+
<p class="text-body-secondary mb-0">Paginated root executions. sub task jobs appear only inside execution detail.</p>
|
|
6
|
+
</div>
|
|
7
|
+
<div>
|
|
8
|
+
<%= link_to "Back to workflows", root_path, class: "btn btn-outline-secondary" %>
|
|
9
|
+
</div>
|
|
10
|
+
</section>
|
|
11
|
+
|
|
12
|
+
<div class="card jw-card">
|
|
13
|
+
<div class="card-body p-0">
|
|
14
|
+
<% if @executions.empty? %>
|
|
15
|
+
<div class="p-4 text-body-secondary">No currently available workflow executions.</div>
|
|
16
|
+
<% else %>
|
|
17
|
+
<div class="table-responsive">
|
|
18
|
+
<table class="table table-hover align-middle mb-0">
|
|
19
|
+
<thead class="table-light">
|
|
20
|
+
<tr>
|
|
21
|
+
<th class="ps-4">Status</th>
|
|
22
|
+
<th>Current task</th>
|
|
23
|
+
<th>Queue</th>
|
|
24
|
+
<th>Job</th>
|
|
25
|
+
<th class="text-end pe-4">Detail</th>
|
|
26
|
+
</tr>
|
|
27
|
+
</thead>
|
|
28
|
+
<tbody>
|
|
29
|
+
<% @executions.each do |execution| %>
|
|
30
|
+
<% status_class = case execution.workflow_status
|
|
31
|
+
when :succeeded then "text-bg-success"
|
|
32
|
+
when :failed then "text-bg-danger"
|
|
33
|
+
when :running then "text-bg-primary"
|
|
34
|
+
else "text-bg-secondary"
|
|
35
|
+
end %>
|
|
36
|
+
<tr>
|
|
37
|
+
<td class="ps-4"><span class="badge <%= status_class %>"><%= execution.workflow_status %></span></td>
|
|
38
|
+
<td><%= execution.current_task_name || "-" %></td>
|
|
39
|
+
<td><span class="jw-mono"><%= execution.queue_name || "-" %></span></td>
|
|
40
|
+
<td class="jw-mono"><%= execution.job_id %></td>
|
|
41
|
+
<td class="text-end pe-4">
|
|
42
|
+
<%= link_to "Open", workflow_execution_path(@workflow.name, execution.job_id), class: "btn btn-sm btn-primary" %>
|
|
43
|
+
</td>
|
|
44
|
+
</tr>
|
|
45
|
+
<% end %>
|
|
46
|
+
</tbody>
|
|
47
|
+
</table>
|
|
48
|
+
</div>
|
|
49
|
+
<% end %>
|
|
50
|
+
</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<% if @page.next_cursor %>
|
|
54
|
+
<div class="d-flex justify-content-end mt-3">
|
|
55
|
+
<%= link_to "Next page", workflow_executions_path(@workflow.name, cursor: @page.next_cursor), class: "btn btn-outline-primary" %>
|
|
56
|
+
</div>
|
|
57
|
+
<% end %>
|