ace-coworker 0.6.0

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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.ace-defaults/coworker/config.yml +6 -0
  3. data/.ace-defaults/coworker/roles/integrator.yml +15 -0
  4. data/.ace-defaults/coworker/roles/reviewer.yml +15 -0
  5. data/.ace-defaults/coworker/roles/spec.yml +14 -0
  6. data/.ace-defaults/coworker/roles/worker.yml +13 -0
  7. data/.ace-defaults/coworker/sequences/integrator.yml +20 -0
  8. data/.ace-defaults/coworker/sequences/reviewer.yml +20 -0
  9. data/.ace-defaults/coworker/sequences/spec.yml +16 -0
  10. data/.ace-defaults/coworker/sequences/worker.yml +21 -0
  11. data/.ace-defaults/nav/protocols/wfi-sources/ace-coworker.yml +19 -0
  12. data/CHANGELOG.md +255 -0
  13. data/README.md +98 -0
  14. data/Rakefile +13 -0
  15. data/docs/usage.md +564 -0
  16. data/exe/ace-coworker +16 -0
  17. data/handbook/workflow-instructions/coworker/integrator.wf.md +162 -0
  18. data/handbook/workflow-instructions/coworker/reviewer.wf.md +211 -0
  19. data/handbook/workflow-instructions/coworker/spec.wf.md +100 -0
  20. data/handbook/workflow-instructions/coworker/worker.wf.md +103 -0
  21. data/lib/ace/coworker/atoms/active_executor_rule.rb +71 -0
  22. data/lib/ace/coworker/atoms/brief_formatter.rb +33 -0
  23. data/lib/ace/coworker/atoms/config_schema.rb +121 -0
  24. data/lib/ace/coworker/atoms/integration_gate.rb +92 -0
  25. data/lib/ace/coworker/atoms/outcome_planner.rb +79 -0
  26. data/lib/ace/coworker/atoms/prepare_decision.rb +75 -0
  27. data/lib/ace/coworker/atoms/prompt_template.rb +28 -0
  28. data/lib/ace/coworker/atoms/report_record_formatter.rb +60 -0
  29. data/lib/ace/coworker/atoms/resume_brief_formatter.rb +84 -0
  30. data/lib/ace/coworker/atoms/resume_planner.rb +78 -0
  31. data/lib/ace/coworker/atoms/role_preset_schema.rb +91 -0
  32. data/lib/ace/coworker/atoms/round_record_schema.rb +62 -0
  33. data/lib/ace/coworker/atoms/round_rule.rb +105 -0
  34. data/lib/ace/coworker/cli/commands/commission.rb +100 -0
  35. data/lib/ace/coworker/cli/commands/gate.rb +91 -0
  36. data/lib/ace/coworker/cli/commands/prepare.rb +138 -0
  37. data/lib/ace/coworker/cli/commands/report.rb +79 -0
  38. data/lib/ace/coworker/cli/commands/resume.rb +57 -0
  39. data/lib/ace/coworker/cli/commands/roles.rb +60 -0
  40. data/lib/ace/coworker/cli/commands/rounds.rb +99 -0
  41. data/lib/ace/coworker/cli/commands/start.rb +39 -0
  42. data/lib/ace/coworker/cli/commands/status.rb +95 -0
  43. data/lib/ace/coworker/cli.rb +83 -0
  44. data/lib/ace/coworker/errors.rb +10 -0
  45. data/lib/ace/coworker/models/assignment_snapshot.rb +65 -0
  46. data/lib/ace/coworker/models/brief.rb +38 -0
  47. data/lib/ace/coworker/models/config.rb +54 -0
  48. data/lib/ace/coworker/models/outcome.rb +39 -0
  49. data/lib/ace/coworker/models/preparation.rb +67 -0
  50. data/lib/ace/coworker/models/resume_plan.rb +47 -0
  51. data/lib/ace/coworker/molecules/assignment_metadata.rb +57 -0
  52. data/lib/ace/coworker/molecules/assignment_probe.rb +57 -0
  53. data/lib/ace/coworker/molecules/config_loader.rb +119 -0
  54. data/lib/ace/coworker/molecules/git_state_probe.rb +63 -0
  55. data/lib/ace/coworker/molecules/hitl_reporter.rb +145 -0
  56. data/lib/ace/coworker/molecules/instruction_resolver.rb +82 -0
  57. data/lib/ace/coworker/molecules/project_root.rb +26 -0
  58. data/lib/ace/coworker/molecules/report_state_store.rb +53 -0
  59. data/lib/ace/coworker/molecules/review_round_store.rb +115 -0
  60. data/lib/ace/coworker/molecules/role_preset_loader.rb +95 -0
  61. data/lib/ace/coworker/molecules/role_sequence_composer.rb +245 -0
  62. data/lib/ace/coworker/molecules/step_evidence_reader.rb +60 -0
  63. data/lib/ace/coworker/molecules/step_report_reader.rb +39 -0
  64. data/lib/ace/coworker/molecules/task_probe.rb +40 -0
  65. data/lib/ace/coworker/molecules/task_record_writer.rb +44 -0
  66. data/lib/ace/coworker/molecules/worktree_executor_probe.rb +139 -0
  67. data/lib/ace/coworker/molecules/worktree_provision_probe.rb +137 -0
  68. data/lib/ace/coworker/organisms/commission_orchestrator.rb +148 -0
  69. data/lib/ace/coworker/organisms/prepare_orchestrator.rb +374 -0
  70. data/lib/ace/coworker/organisms/report_orchestrator.rb +192 -0
  71. data/lib/ace/coworker/organisms/resume_orchestrator.rb +91 -0
  72. data/lib/ace/coworker/organisms/start_config_writer.rb +127 -0
  73. data/lib/ace/coworker/organisms/start_orchestrator.rb +45 -0
  74. data/lib/ace/coworker/organisms/status_orchestrator.rb +62 -0
  75. data/lib/ace/coworker/version.rb +7 -0
  76. data/lib/ace/coworker.rb +86 -0
  77. metadata +319 -0
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require_relative "commission_orchestrator"
5
+
6
+ module Ace
7
+ module Coworker
8
+ module Organisms
9
+ # Writes the planner's per-role start configs (L4.3) into the
10
+ # prepared worktree: `.ace-local/coworker/prepare/<role>.yml`, ONE
11
+ # file per sequence leg. Every config is expanded by the SAME
12
+ # commission primitive that writes the default `config.yml`, so the
13
+ # round-trip guarantee ("what commission writes, start accepts")
14
+ # holds by construction and the ownership split stays one writer per
15
+ # file: `prepare` owns `prepare/<role>.yml`; the default config.yml
16
+ # (or any `--config` target) remains `commission`'s alone.
17
+ # Idempotent: a leg whose file already holds the identical content
18
+ # is reported as "reused" without a write; changed content (e.g. a
19
+ # different overseer) is overwritten deterministically ("updated") —
20
+ # prepare is the single writer of these files. No secrets, no
21
+ # assignment steps: only the seven documented config fields.
22
+ class StartConfigWriter
23
+ PREPARE_DIR = File.join(".ace-local", "coworker", "prepare")
24
+
25
+ # @param worktree_path [String] absolute path of the prepared worktree
26
+ # @param commission_factory [#call] test seam building a
27
+ # CommissionOrchestrator for (worktree_path, target)
28
+ def initialize(worktree_path:, commission_factory: nil)
29
+ @worktree_path = worktree_path
30
+ @commission_factory = commission_factory || method(:default_commission)
31
+ end
32
+
33
+ # @param task [String] canonical task id
34
+ # @param sequence [Array<Hash>] composed role-sequence entries
35
+ # ({"role" =>, "assignment" =>, …} from RoleSequenceComposer)
36
+ # @param overseer [String] reporting address for every leg
37
+ # @param dry_run [Boolean] resolve and validate without writes
38
+ # @return [Array<Hash>] {"role", "assignment", "path", "disposition"}
39
+ # disposition: "created" | "reused" | "updated" | "planned" (dry-run)
40
+ # @raise [Error] when a leg cannot be commissioned (unknown role,
41
+ # task/assignment mismatch, invalid assembly)
42
+ def call(task:, sequence:, overseer:, dry_run: false)
43
+ validate_role_names!(Array(sequence))
44
+
45
+ # Pre-resolve EVERY leg first (dry-run commission pass): a late
46
+ # leg failure must not leave earlier leg configs on disk — the
47
+ # same all-or-nothing pattern RoleSequenceComposer established.
48
+ # Legs composed under dry_run (a planned sequence, no assignment
49
+ # id yet) cannot be identity-checked against ace-assign, so they
50
+ # are planned as-is; a real run requires a composed assignment.
51
+ resolved_legs = Array(sequence).map do |entry|
52
+ unless dry_run || !entry["assignment"].to_s.strip.empty?
53
+ raise Error, "role '#{entry['role']}' has no composed assignment; " \
54
+ "compose the sequence (prepare without --dry-run) before writing its start config"
55
+ end
56
+
57
+ entry = entry.dup
58
+ entry["task"] = task
59
+ entry["overseer"] = overseer
60
+ entry["resolved_config"] =
61
+ entry["assignment"].to_s.strip.empty? ? nil : resolve_leg(entry)
62
+ entry
63
+ end
64
+
65
+ resolved_legs.map { |entry| write_leg(entry, dry_run: dry_run) }
66
+ end
67
+
68
+ private
69
+
70
+ def validate_role_names!(sequence)
71
+ sequence.each do |entry|
72
+ role = entry["role"].to_s
73
+ unless role.match?(/\A[\w.-]+\z/) && !role.match?(/\A\.+\z/)
74
+ raise Error, "invalid role name '#{role}' for start config"
75
+ end
76
+ end
77
+ end
78
+
79
+ def resolve_leg(entry)
80
+ commission = @commission_factory.call(@worktree_path,
81
+ target_path(entry["role"]))
82
+ # dry-run commission resolves, identity-checks, and schema-validates
83
+ # the leg config without touching the disk.
84
+ resolved = commission.call(role: entry["role"], task: entry["task"],
85
+ assignment: entry["assignment"], overseer: entry["overseer"],
86
+ force: true, dry_run: true)
87
+ YAML.safe_dump(resolved.config)
88
+ end
89
+
90
+ def target_path(role)
91
+ File.join(@worktree_path, PREPARE_DIR, "#{role}.yml")
92
+ end
93
+
94
+ def write_leg(entry, dry_run:)
95
+ role = entry["role"]
96
+ content = entry["resolved_config"]
97
+ target = target_path(role)
98
+
99
+ existing = File.file?(target) ? File.read(target) : nil
100
+ disposition = if dry_run
101
+ "planned"
102
+ elsif existing == content
103
+ "reused"
104
+ else
105
+ commission = @commission_factory.call(@worktree_path, target)
106
+ commission.call(role: role, task: entry["task"],
107
+ assignment: entry["assignment"], overseer: entry["overseer"],
108
+ force: true, dry_run: false)
109
+ existing.nil? ? "created" : "updated"
110
+ end
111
+
112
+ {"role" => role, "assignment" => entry["assignment"],
113
+ "path" => File.join(PREPARE_DIR, "#{role}.yml"), "disposition" => disposition}
114
+ end
115
+
116
+ def default_commission(worktree_path, target)
117
+ CommissionOrchestrator.new(
118
+ project_root: worktree_path,
119
+ preset_loader: Molecules::RolePresetLoader.new(project_root: worktree_path),
120
+ task_probe: Molecules::TaskProbe.new(project_root: worktree_path),
121
+ assignment_metadata: Molecules::AssignmentMetadata.new(project_root: worktree_path),
122
+ config_path: target)
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ace
4
+ module Coworker
5
+ module Organisms
6
+ # Orchestrates `ace-coworker start`: load+validate config, resolve the
7
+ # task in this worktree, verify the assignment exists and matches the
8
+ # config task, resolve the instruction source, and render the executor
9
+ # brief. Writes nothing; never creates a substitute assignment/worktree.
10
+ class StartOrchestrator
11
+ def initialize(project_root: nil, config_loader: nil, task_probe: nil, assignment_metadata: nil,
12
+ assignment_probe: nil, instruction_resolver: nil, config: nil)
13
+ @config = config || Ace::Coworker.config
14
+ @project_root = project_root || Molecules::ProjectRoot.new.resolve
15
+ @config_loader = config_loader || Molecules::ConfigLoader.new(project_root: @project_root, defaults: @config)
16
+ @task_probe = task_probe || Molecules::TaskProbe.new(project_root: @project_root)
17
+ @assignment_metadata = assignment_metadata || Molecules::AssignmentMetadata.new(project_root: @project_root)
18
+ @assignment_probe = assignment_probe || Molecules::AssignmentProbe.new(project_root: @project_root)
19
+ @instruction_resolver = instruction_resolver || Molecules::InstructionResolver.new(project_root: @project_root)
20
+ end
21
+
22
+ attr_reader :project_root
23
+
24
+ # @return [Models::Brief]
25
+ # @raise [Error] with a specific "not ready"/invalid/mismatch message
26
+ def call(config_path: nil)
27
+ cfg = @config_loader.load(path: config_path)
28
+
29
+ task_path = @task_probe.resolve!(cfg.task)
30
+ @assignment_metadata.verify_task_match!(cfg.assignment, cfg.task)
31
+ snapshot = @assignment_probe.snapshot(cfg.assignment)
32
+ instructions_source = @instruction_resolver.resolve!(cfg.instructions)
33
+
34
+ Models::Brief.new(
35
+ config: cfg,
36
+ instructions_source: instructions_source,
37
+ task_path: task_path,
38
+ assignment_snapshot: snapshot,
39
+ project_root: @project_root
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ace
4
+ module Coworker
5
+ module Organisms
6
+ # Orchestrates `ace-coworker status`: readiness, resolved identity,
7
+ # assignment progress, completion verdict. A query — renders any state,
8
+ # including not-ready, without guessing.
9
+ class StatusOrchestrator
10
+ NotReady = Struct.new(:message, keyword_init: true)
11
+ Ready = Struct.new(:config, :snapshot, :project_root, :probe_error, :assignment, keyword_init: true)
12
+
13
+ def initialize(project_root: nil, config_loader: nil, assignment_metadata: nil,
14
+ assignment_probe: nil, config: nil)
15
+ @config = config || Ace::Coworker.config
16
+ @project_root = project_root || Molecules::ProjectRoot.new.resolve
17
+ @config_loader = config_loader || Molecules::ConfigLoader.new(project_root: @project_root, defaults: @config)
18
+ @assignment_metadata = assignment_metadata || Molecules::AssignmentMetadata.new(project_root: @project_root)
19
+ @assignment_probe = assignment_probe || Molecules::AssignmentProbe.new(project_root: @project_root)
20
+ end
21
+
22
+ attr_reader :project_root
23
+
24
+ # @return [NotReady, Ready]
25
+ def call(config_path: nil, assignment: nil)
26
+ # Same resolution rule as ConfigLoader: explicit paths are expanded
27
+ # against the project root, not the process working directory.
28
+ target = config_path ? File.expand_path(config_path, @project_root) : default_config_path
29
+ relative = relativize(target)
30
+ return NotReady.new(message: "not ready: #{relative} not found") unless File.file?(target)
31
+
32
+ begin
33
+ cfg = @config_loader.load(path: target)
34
+ rescue Error => e
35
+ return NotReady.new(message: e.message)
36
+ end
37
+
38
+ assignment_id = assignment.to_s.strip.empty? ? cfg.assignment : assignment.to_s.strip
39
+ begin
40
+ @assignment_metadata.verify_task_match!(assignment_id, cfg.task)
41
+ snapshot = @assignment_probe.snapshot(assignment_id)
42
+ rescue Error => e
43
+ return Ready.new(config: cfg, snapshot: nil, project_root: @project_root,
44
+ probe_error: e.message, assignment: assignment_id)
45
+ end
46
+
47
+ Ready.new(config: cfg, snapshot: snapshot, project_root: @project_root, assignment: assignment_id)
48
+ end
49
+
50
+ private
51
+
52
+ def default_config_path
53
+ @config_loader.config_path
54
+ end
55
+
56
+ def relativize(path)
57
+ path.start_with?(@project_root) ? path.delete_prefix("#{@project_root}/") : path
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ace
4
+ module Coworker
5
+ VERSION = "0.6.0"
6
+ end
7
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
4
+ require "ace/support/config"
5
+ require_relative "coworker/version"
6
+ require_relative "coworker/errors"
7
+
8
+ module Ace
9
+ module Coworker
10
+ require_relative "coworker/models/config"
11
+ require_relative "coworker/models/brief"
12
+ require_relative "coworker/models/assignment_snapshot"
13
+ require_relative "coworker/models/outcome"
14
+ require_relative "coworker/models/resume_plan"
15
+ require_relative "coworker/models/preparation"
16
+
17
+ autoload :CLI, "ace/coworker/cli"
18
+
19
+ module Atoms
20
+ autoload :ConfigSchema, "ace/coworker/atoms/config_schema"
21
+ autoload :BriefFormatter, "ace/coworker/atoms/brief_formatter"
22
+ autoload :OutcomePlanner, "ace/coworker/atoms/outcome_planner"
23
+ autoload :ReportRecordFormatter, "ace/coworker/atoms/report_record_formatter"
24
+ autoload :ResumePlanner, "ace/coworker/atoms/resume_planner"
25
+ autoload :ResumeBriefFormatter, "ace/coworker/atoms/resume_brief_formatter"
26
+ autoload :PrepareDecision, "ace/coworker/atoms/prepare_decision"
27
+ autoload :ActiveExecutorRule, "ace/coworker/atoms/active_executor_rule"
28
+ autoload :RolePresetSchema, "ace/coworker/atoms/role_preset_schema"
29
+ autoload :PromptTemplate, "ace/coworker/atoms/prompt_template"
30
+ autoload :RoundRule, "ace/coworker/atoms/round_rule"
31
+ autoload :RoundRecordSchema, "ace/coworker/atoms/round_record_schema"
32
+ autoload :IntegrationGate, "ace/coworker/atoms/integration_gate"
33
+ end
34
+
35
+ module Molecules
36
+ autoload :ProjectRoot, "ace/coworker/molecules/project_root"
37
+ autoload :ConfigLoader, "ace/coworker/molecules/config_loader"
38
+ autoload :TaskProbe, "ace/coworker/molecules/task_probe"
39
+ autoload :AssignmentMetadata, "ace/coworker/molecules/assignment_metadata"
40
+ autoload :AssignmentProbe, "ace/coworker/molecules/assignment_probe"
41
+ autoload :InstructionResolver, "ace/coworker/molecules/instruction_resolver"
42
+ autoload :StepEvidenceReader, "ace/coworker/molecules/step_evidence_reader"
43
+ autoload :HitlReporter, "ace/coworker/molecules/hitl_reporter"
44
+ autoload :TaskRecordWriter, "ace/coworker/molecules/task_record_writer"
45
+ autoload :ReportStateStore, "ace/coworker/molecules/report_state_store"
46
+ autoload :StepReportReader, "ace/coworker/molecules/step_report_reader"
47
+ autoload :GitStateProbe, "ace/coworker/molecules/git_state_probe"
48
+ autoload :WorktreeProvisionProbe, "ace/coworker/molecules/worktree_provision_probe"
49
+ autoload :WorktreeExecutorProbe, "ace/coworker/molecules/worktree_executor_probe"
50
+ autoload :RolePresetLoader, "ace/coworker/molecules/role_preset_loader"
51
+ autoload :ReviewRoundStore, "ace/coworker/molecules/review_round_store"
52
+ autoload :RoleSequenceComposer, "ace/coworker/molecules/role_sequence_composer"
53
+ end
54
+
55
+ module Organisms
56
+ autoload :StartOrchestrator, "ace/coworker/organisms/start_orchestrator"
57
+ autoload :StatusOrchestrator, "ace/coworker/organisms/status_orchestrator"
58
+ autoload :ReportOrchestrator, "ace/coworker/organisms/report_orchestrator"
59
+ autoload :ResumeOrchestrator, "ace/coworker/organisms/resume_orchestrator"
60
+ autoload :PrepareOrchestrator, "ace/coworker/organisms/prepare_orchestrator"
61
+ autoload :CommissionOrchestrator, "ace/coworker/organisms/commission_orchestrator"
62
+ autoload :StartConfigWriter, "ace/coworker/organisms/start_config_writer"
63
+ end
64
+
65
+ def self.config
66
+ @config ||= begin
67
+ defaults = load_gem_defaults
68
+ user_config = Ace::Support::Config.create.resolve_namespace("coworker").to_h
69
+ Ace::Support::Config::Models::Config.wrap(defaults, user_config, source: "coworker")
70
+ end
71
+ end
72
+
73
+ def self.load_gem_defaults
74
+ gem_root = ::Gem.loaded_specs["ace-coworker"]&.gem_dir || File.expand_path("../..", __dir__)
75
+ defaults_path = File.join(gem_root, ".ace-defaults", "coworker", "config.yml")
76
+ raise Error, "Default config not found: #{defaults_path}" unless File.exist?(defaults_path)
77
+
78
+ YAML.safe_load_file(defaults_path, permitted_classes: [Date], aliases: true) || {}
79
+ end
80
+ private_class_method :load_gem_defaults
81
+
82
+ def self.reset_config!
83
+ @config = nil
84
+ end
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,319 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ace-coworker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Michal Czyz
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2026-10-20 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ace-support-cli
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '0.6'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '0.6'
26
+ - !ruby/object:Gem::Dependency
27
+ name: ace-support-core
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '0.31'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '0.31'
40
+ - !ruby/object:Gem::Dependency
41
+ name: ace-support-config
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.18'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.18'
54
+ - !ruby/object:Gem::Dependency
55
+ name: ace-support-fs
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.3'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '0.3'
68
+ - !ruby/object:Gem::Dependency
69
+ name: ace-support-nav
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.28'
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '0.28'
82
+ - !ruby/object:Gem::Dependency
83
+ name: ace-task
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '0.41'
89
+ type: :runtime
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.41'
96
+ - !ruby/object:Gem::Dependency
97
+ name: ace-assign
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.72'
103
+ type: :runtime
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.72'
110
+ - !ruby/object:Gem::Dependency
111
+ name: ace-hitl
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.22'
117
+ type: :runtime
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '0.22'
124
+ - !ruby/object:Gem::Dependency
125
+ name: ace-git-worktree
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '0.27'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '0.27'
138
+ - !ruby/object:Gem::Dependency
139
+ name: ace-review
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: '0.62'
145
+ type: :runtime
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: '0.62'
152
+ - !ruby/object:Gem::Dependency
153
+ name: ace-support-test-helpers
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '0.14'
159
+ type: :development
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '0.14'
166
+ - !ruby/object:Gem::Dependency
167
+ name: bundler
168
+ requirement: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - "~>"
171
+ - !ruby/object:Gem::Version
172
+ version: '2.0'
173
+ type: :development
174
+ prerelease: false
175
+ version_requirements: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '2.0'
180
+ - !ruby/object:Gem::Dependency
181
+ name: minitest
182
+ requirement: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - "~>"
185
+ - !ruby/object:Gem::Version
186
+ version: '5.0'
187
+ type: :development
188
+ prerelease: false
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - "~>"
192
+ - !ruby/object:Gem::Version
193
+ version: '5.0'
194
+ - !ruby/object:Gem::Dependency
195
+ name: rake
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - "~>"
199
+ - !ruby/object:Gem::Version
200
+ version: '13.0'
201
+ type: :development
202
+ prerelease: false
203
+ version_requirements: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - "~>"
206
+ - !ruby/object:Gem::Version
207
+ version: '13.0'
208
+ description: ace-coworker composes the existing ace-assign lifecycle, ace-task ref
209
+ resolution, and ace-hitl reporting for a prepared executor role. It owns the .ace-local/coworker/
210
+ run configuration and renders the executor brief.
211
+ email:
212
+ - mc@cs3b.com
213
+ executables:
214
+ - ace-coworker
215
+ extensions: []
216
+ extra_rdoc_files: []
217
+ files:
218
+ - ".ace-defaults/coworker/config.yml"
219
+ - ".ace-defaults/coworker/roles/integrator.yml"
220
+ - ".ace-defaults/coworker/roles/reviewer.yml"
221
+ - ".ace-defaults/coworker/roles/spec.yml"
222
+ - ".ace-defaults/coworker/roles/worker.yml"
223
+ - ".ace-defaults/coworker/sequences/integrator.yml"
224
+ - ".ace-defaults/coworker/sequences/reviewer.yml"
225
+ - ".ace-defaults/coworker/sequences/spec.yml"
226
+ - ".ace-defaults/coworker/sequences/worker.yml"
227
+ - ".ace-defaults/nav/protocols/wfi-sources/ace-coworker.yml"
228
+ - CHANGELOG.md
229
+ - README.md
230
+ - Rakefile
231
+ - docs/usage.md
232
+ - exe/ace-coworker
233
+ - handbook/workflow-instructions/coworker/integrator.wf.md
234
+ - handbook/workflow-instructions/coworker/reviewer.wf.md
235
+ - handbook/workflow-instructions/coworker/spec.wf.md
236
+ - handbook/workflow-instructions/coworker/worker.wf.md
237
+ - lib/ace/coworker.rb
238
+ - lib/ace/coworker/atoms/active_executor_rule.rb
239
+ - lib/ace/coworker/atoms/brief_formatter.rb
240
+ - lib/ace/coworker/atoms/config_schema.rb
241
+ - lib/ace/coworker/atoms/integration_gate.rb
242
+ - lib/ace/coworker/atoms/outcome_planner.rb
243
+ - lib/ace/coworker/atoms/prepare_decision.rb
244
+ - lib/ace/coworker/atoms/prompt_template.rb
245
+ - lib/ace/coworker/atoms/report_record_formatter.rb
246
+ - lib/ace/coworker/atoms/resume_brief_formatter.rb
247
+ - lib/ace/coworker/atoms/resume_planner.rb
248
+ - lib/ace/coworker/atoms/role_preset_schema.rb
249
+ - lib/ace/coworker/atoms/round_record_schema.rb
250
+ - lib/ace/coworker/atoms/round_rule.rb
251
+ - lib/ace/coworker/cli.rb
252
+ - lib/ace/coworker/cli/commands/commission.rb
253
+ - lib/ace/coworker/cli/commands/gate.rb
254
+ - lib/ace/coworker/cli/commands/prepare.rb
255
+ - lib/ace/coworker/cli/commands/report.rb
256
+ - lib/ace/coworker/cli/commands/resume.rb
257
+ - lib/ace/coworker/cli/commands/roles.rb
258
+ - lib/ace/coworker/cli/commands/rounds.rb
259
+ - lib/ace/coworker/cli/commands/start.rb
260
+ - lib/ace/coworker/cli/commands/status.rb
261
+ - lib/ace/coworker/errors.rb
262
+ - lib/ace/coworker/models/assignment_snapshot.rb
263
+ - lib/ace/coworker/models/brief.rb
264
+ - lib/ace/coworker/models/config.rb
265
+ - lib/ace/coworker/models/outcome.rb
266
+ - lib/ace/coworker/models/preparation.rb
267
+ - lib/ace/coworker/models/resume_plan.rb
268
+ - lib/ace/coworker/molecules/assignment_metadata.rb
269
+ - lib/ace/coworker/molecules/assignment_probe.rb
270
+ - lib/ace/coworker/molecules/config_loader.rb
271
+ - lib/ace/coworker/molecules/git_state_probe.rb
272
+ - lib/ace/coworker/molecules/hitl_reporter.rb
273
+ - lib/ace/coworker/molecules/instruction_resolver.rb
274
+ - lib/ace/coworker/molecules/project_root.rb
275
+ - lib/ace/coworker/molecules/report_state_store.rb
276
+ - lib/ace/coworker/molecules/review_round_store.rb
277
+ - lib/ace/coworker/molecules/role_preset_loader.rb
278
+ - lib/ace/coworker/molecules/role_sequence_composer.rb
279
+ - lib/ace/coworker/molecules/step_evidence_reader.rb
280
+ - lib/ace/coworker/molecules/step_report_reader.rb
281
+ - lib/ace/coworker/molecules/task_probe.rb
282
+ - lib/ace/coworker/molecules/task_record_writer.rb
283
+ - lib/ace/coworker/molecules/worktree_executor_probe.rb
284
+ - lib/ace/coworker/molecules/worktree_provision_probe.rb
285
+ - lib/ace/coworker/organisms/commission_orchestrator.rb
286
+ - lib/ace/coworker/organisms/prepare_orchestrator.rb
287
+ - lib/ace/coworker/organisms/report_orchestrator.rb
288
+ - lib/ace/coworker/organisms/resume_orchestrator.rb
289
+ - lib/ace/coworker/organisms/start_config_writer.rb
290
+ - lib/ace/coworker/organisms/start_orchestrator.rb
291
+ - lib/ace/coworker/organisms/status_orchestrator.rb
292
+ - lib/ace/coworker/version.rb
293
+ homepage: https://github.com/cs3b/ace
294
+ licenses:
295
+ - MIT
296
+ metadata:
297
+ allowed_push_host: https://rubygems.org
298
+ homepage_uri: https://github.com/cs3b/ace
299
+ source_code_uri: https://github.com/cs3b/ace/tree/main/ace-coworker/
300
+ changelog_uri: https://github.com/cs3b/ace/blob/main/ace-coworker/CHANGELOG.md
301
+ rdoc_options: []
302
+ require_paths:
303
+ - lib
304
+ required_ruby_version: !ruby/object:Gem::Requirement
305
+ requirements:
306
+ - - ">="
307
+ - !ruby/object:Gem::Version
308
+ version: 3.2.0
309
+ required_rubygems_version: !ruby/object:Gem::Requirement
310
+ requirements:
311
+ - - ">="
312
+ - !ruby/object:Gem::Version
313
+ version: '0'
314
+ requirements: []
315
+ rubygems_version: 3.6.9
316
+ specification_version: 4
317
+ summary: Prepared executor that reads .ace-local/coworker/ and drives its ace-assign
318
+ assignment
319
+ test_files: []