ace-assign 0.42.4 → 0.53.4

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.ace-defaults/assign/catalog/composition-rules.yml +2 -17
  3. data/.ace-defaults/assign/catalog/steps/create-pr.step.yml +0 -26
  4. data/.ace-defaults/assign/catalog/steps/create-retro.step.yml +1 -1
  5. data/.ace-defaults/assign/catalog/steps/mark-task-done.step.yml +1 -2
  6. data/.ace-defaults/assign/catalog/steps/onboard.step.yml +0 -17
  7. data/.ace-defaults/assign/catalog/steps/plan-task.step.yml +0 -11
  8. data/.ace-defaults/assign/catalog/steps/pre-commit-review.step.yml +3 -0
  9. data/.ace-defaults/assign/catalog/steps/reflect-and-refactor.step.yml +3 -2
  10. data/.ace-defaults/assign/catalog/steps/review-pr.step.yml +0 -16
  11. data/.ace-defaults/assign/catalog/steps/task-load.step.yml +1 -1
  12. data/.ace-defaults/assign/catalog/steps/verify-test-suite.step.yml +7 -34
  13. data/.ace-defaults/assign/catalog/steps/verify-test.step.yml +7 -4
  14. data/.ace-defaults/assign/catalog/steps/work-on-task.step.yml +0 -17
  15. data/.ace-defaults/assign/presets/fix-bug.yml +4 -3
  16. data/.ace-defaults/assign/presets/quick-implement.yml +1 -1
  17. data/.ace-defaults/assign/presets/work-on-task.yml +3 -16
  18. data/CHANGELOG.md +201 -0
  19. data/README.md +20 -43
  20. data/docs/demo/canonical-skill-source.gif +0 -0
  21. data/docs/demo/canonical-skill-source.tape.yml +51 -0
  22. data/docs/demo/fork-provider.cast +957 -0
  23. data/docs/demo/fork-provider.gif +0 -0
  24. data/docs/demo/fork-provider.recording.json +32 -0
  25. data/docs/demo/fork-provider.tape.yml +65 -20
  26. data/docs/getting-started.md +5 -2
  27. data/docs/usage.md +47 -0
  28. data/handbook/guides/fork-context.g.md +2 -2
  29. data/handbook/skills/as-assign-drive/SKILL.md +13 -1
  30. data/handbook/skills/as-create-retro-internal/SKILL.md +29 -0
  31. data/handbook/skills/as-mark-task-done-internal/SKILL.md +29 -0
  32. data/handbook/skills/as-reflect-and-refactor-internal/SKILL.md +30 -0
  33. data/handbook/skills/as-task-load-internal/SKILL.md +28 -0
  34. data/handbook/workflow-instructions/assign/compose.wf.md +3 -3
  35. data/handbook/workflow-instructions/assign/create-retro-internal.wf.md +11 -0
  36. data/handbook/workflow-instructions/assign/create.wf.md +6 -3
  37. data/handbook/workflow-instructions/assign/drive.wf.md +231 -14
  38. data/handbook/workflow-instructions/assign/mark-task-done-internal.wf.md +12 -0
  39. data/handbook/workflow-instructions/assign/prepare.wf.md +5 -5
  40. data/handbook/workflow-instructions/assign/reflect-and-refactor-internal.wf.md +14 -0
  41. data/handbook/workflow-instructions/assign/run-in-batches.wf.md +4 -1
  42. data/handbook/workflow-instructions/assign/start.wf.md +5 -2
  43. data/handbook/workflow-instructions/assign/task-load-internal.wf.md +12 -0
  44. data/handbook/workflow-instructions/assign/verify-test-suite.wf.md +36 -0
  45. data/lib/ace/assign/atoms/catalog_loader.rb +105 -2
  46. data/lib/ace/assign/atoms/step_file_parser.rb +15 -0
  47. data/lib/ace/assign/cli/commands/assignment_target.rb +53 -0
  48. data/lib/ace/assign/cli/commands/finish.rb +7 -4
  49. data/lib/ace/assign/cli/commands/fork_run.rb +4 -1
  50. data/lib/ace/assign/cli/commands/fork_session.rb +52 -0
  51. data/lib/ace/assign/cli/commands/start.rb +9 -3
  52. data/lib/ace/assign/cli/commands/status.rb +208 -227
  53. data/lib/ace/assign/cli/commands/step.rb +62 -0
  54. data/lib/ace/assign/cli.rb +8 -1
  55. data/lib/ace/assign/models/step.rb +4 -2
  56. data/lib/ace/assign/molecules/fork_session_launcher.rb +189 -8
  57. data/lib/ace/assign/molecules/queue_scanner.rb +1 -0
  58. data/lib/ace/assign/molecules/skill_assign_source_resolver.rb +223 -47
  59. data/lib/ace/assign/molecules/tmux_fork_runner.rb +191 -0
  60. data/lib/ace/assign/organisms/assignment_executor.rb +223 -24
  61. data/lib/ace/assign/version.rb +1 -1
  62. metadata +21 -5
  63. data/.ace-defaults/assign/catalog/steps/verify-e2e.step.yml +0 -42
@@ -12,15 +12,40 @@ module Ace
12
12
  # start → advance → complete (with fail/add/retry branches)
13
13
  class AssignmentExecutor
14
14
  DEFAULT_DYNAMIC_STEP_INSTRUCTIONS = "Complete this step and finish with: ace-assign finish --message report.md".freeze
15
+ PROJECT_ROOT_SIGNAL = "project_root".freeze
16
+ CATALOG_SIGNAL = "catalog".freeze
15
17
 
16
18
  attr_reader :assignment_manager, :queue_scanner, :step_writer, :step_renumberer, :skill_source_resolver
17
19
 
18
- def initialize(cache_base: nil)
20
+ class << self
21
+ def clear_caches!
22
+ @cache_store = { step_catalog_cache: {} }
23
+ end
24
+
25
+ def cache_store
26
+ @cache_store ||= { step_catalog_cache: {} }
27
+ end
28
+
29
+ private
30
+
31
+ def cached_value(store_key, key)
32
+ cache_store[store_key][key]
33
+ end
34
+
35
+ def store_cached_value(store_key, key, value)
36
+ cache_store[store_key][key] = value
37
+ end
38
+ end
39
+
40
+ def initialize(cache_base: nil, skill_source_resolver: nil, step_catalog: nil)
19
41
  @assignment_manager = Molecules::AssignmentManager.new(cache_base: cache_base)
20
42
  @queue_scanner = Molecules::QueueScanner.new
21
43
  @step_writer = Molecules::StepWriter.new
22
- @skill_source_resolver = Molecules::SkillAssignSourceResolver.new
44
+ @skill_source_resolver = skill_source_resolver || Molecules::SkillAssignSourceResolver.new
23
45
  @step_catalog = nil
46
+ @step_catalog_from_fixture = step_catalog
47
+ @step_catalog_from_fixture_set = !step_catalog.nil?
48
+ @step_catalog_loaded = false
24
49
  @step_renumberer = Molecules::StepRenumberer.new(
25
50
  step_writer: @step_writer,
26
51
  queue_scanner: @queue_scanner
@@ -573,7 +598,10 @@ module Ace
573
598
  # @param sub_steps [Array<String>] Declared sub-step names
574
599
  # @return [Hash] Parent step config for runtime queue
575
600
  def build_split_parent_step(step:, parent_number:, parent_context:, sub_steps:)
576
- source_skill = step["skill"]
601
+ source_skill = step["source_skill"] || step["skill"]
602
+ if (source_skill.nil? || source_skill.to_s.strip.empty?) && step["source"].to_s.start_with?("skill://")
603
+ source_skill = step["source"].to_s.delete_prefix("skill://").strip
604
+ end
577
605
  original_text = normalize_instructions(step["instructions"]).strip
578
606
  definition = find_step_definition("split-subtree-root") || {}
579
607
 
@@ -600,6 +628,7 @@ module Ace
600
628
  )
601
629
  parent_step.delete("sub_steps")
602
630
  parent_step.delete("sub-steps")
631
+ parent_step.delete("source")
603
632
  parent_step.delete("skill")
604
633
  parent_step.delete("workflow")
605
634
  parent_step["source_skill"] = source_skill if source_skill
@@ -712,6 +741,13 @@ module Ace
712
741
  child["workflow"] = step_def["workflow"] if step_def["workflow"]
713
742
  preserve_explicit_skill = (sub_steps_origin == "explicit")
714
743
  child["skill"] = step_def["skill"] if step_def["skill"] && (preserve_explicit_skill || !step_def["workflow"])
744
+ child["source"] = if step_def["source"]
745
+ step_def["source"]
746
+ elsif step_def["workflow"]
747
+ step_def["workflow"]
748
+ elsif step_def["skill"]
749
+ "skill://#{step_def["skill"]}"
750
+ end
715
751
 
716
752
  context_default = step_def.dig("context", "default")
717
753
  child["context"] = context_default if context_default && !fork_context_value?(parent_context)
@@ -811,14 +847,9 @@ module Ace
811
847
  when "pre-commit-review"
812
848
  pre_commit_review_action_instructions(task_hint: task_hint)
813
849
  when "verify-test"
814
- "- Identify modified packages#{task_hint}.\n- For each modified package, run: cd <package> && ace-test --profile 6\n- If no package-level code changes are present, mark this step skipped with a clear reason."
850
+ "- Identify modified packages#{task_hint}.\n- For each modified package, run: cd <package> && ace-test all --profile 6\n- This subtree step verifies modified packages only; do not run the monorepo suite here.\n- If no package-level code changes are present, mark this step skipped with a clear reason."
815
851
  when /\Arelease(?:-.+)?\z/
816
852
  "- Release all modified packages and update both package and root changelogs.\n- Follow semantic versioning expectations for this step.\n- When auto-detecting packages, include `git diff origin/main...HEAD --name-only` in addition to working-tree state — prior steps may have already committed changes."
817
- when "verify-e2e"
818
- "- Check change scope: run `git diff origin/main --name-only` to list modified files.\n" \
819
- "- **Skip criteria**: If ALL modified files match `*.md`, `*.yml` (non-CI config), `.ace-tasks/**`, or `.ace-retros/**`, skip E2E verification — mark step done with \"skipped: docs/task-spec only changes, no runnable code affected\".\n" \
820
- "- Otherwise: detect modified packages, run E2E scenarios for each package with `test/e2e/` scenarios#{task_hint}.\n" \
821
- "- If no modified package has E2E scenarios, mark step done with \"skipped: no E2E scenarios for modified packages\"."
822
853
  else
823
854
  "- Execute the #{sub_name} step."
824
855
  end
@@ -861,6 +892,8 @@ module Ace
861
892
  "instructions" => rendered_instructions,
862
893
  "workflow" => rendering["workflow"]
863
894
  )
895
+ resolved_source = resolved_step_source(step, rendering)
896
+ materialized["source"] = resolved_source if resolved_source && !resolved_source.empty?
864
897
  unless split_child_without_explicit_fork?(step)
865
898
  context_default = rendering.dig("context", "default")
866
899
  materialized["context"] ||= context_default if context_default
@@ -879,6 +912,24 @@ module Ace
879
912
  end
880
913
 
881
914
  def resolve_step_rendering(step)
915
+ explicit_source = step["source"]&.to_s&.strip
916
+ if explicit_source && !explicit_source.empty?
917
+ canonical_step = find_step_definition_with_source_fallback(step, explicit_source: explicit_source)
918
+ if canonical_step && split_child_without_explicit_fork?(step)
919
+ canonical_step = canonical_step.dup
920
+ canonical_step.delete("context")
921
+ canonical_step.delete("fork")
922
+ end
923
+ source_skill = step["source_skill"]&.to_s&.strip
924
+ source_skill = canonical_step&.dig("source_skill") if source_skill.nil? || source_skill.empty?
925
+ rendering = skill_source_resolver.resolve_source_rendering(
926
+ explicit_source,
927
+ step_name: step["name"]&.to_s,
928
+ source_skill: source_skill
929
+ )
930
+ return canonical_step ? canonical_step.merge(rendering || {}) : rendering if rendering
931
+ end
932
+
882
933
  explicit_workflow = step["workflow"]&.to_s&.strip
883
934
  if explicit_workflow && !explicit_workflow.empty?
884
935
  canonical_step = find_step_definition(step["name"]&.to_s)
@@ -1039,6 +1090,15 @@ module Ace
1039
1090
  end
1040
1091
 
1041
1092
  def resolve_step_assign_config(step)
1093
+ source_ref = step["source"]&.to_s&.strip
1094
+ if source_ref && !source_ref.empty?
1095
+ return skill_source_resolver.resolve_source_assign_config(
1096
+ source_ref,
1097
+ step_name: step["name"]&.to_s,
1098
+ source_skill: step["source_skill"]&.to_s
1099
+ )
1100
+ end
1101
+
1042
1102
  explicit_workflow = step["workflow"]&.to_s&.strip
1043
1103
  if explicit_workflow && !explicit_workflow.empty?
1044
1104
  return skill_source_resolver.resolve_workflow_assign_config(
@@ -1119,28 +1179,118 @@ module Ace
1119
1179
  Atoms::CatalogLoader.find_by_name(step_catalog, step_name)
1120
1180
  end
1121
1181
 
1182
+ def find_step_definition_with_source_fallback(step, explicit_source:)
1183
+ step_name = step["name"]&.to_s
1184
+ canonical_step = find_step_definition(step_name)
1185
+ return canonical_step if canonical_step
1186
+
1187
+ source = explicit_source.to_s.strip
1188
+ return nil if source.empty?
1189
+
1190
+ source_skill = step["source_skill"]&.to_s&.strip
1191
+ source_skill = source.delete_prefix("skill://").strip if source_skill.to_s.empty? && source.start_with?("skill://")
1192
+
1193
+ step_catalog.find do |entry|
1194
+ next unless entry.is_a?(Hash)
1195
+
1196
+ entry_source = entry["source"]&.to_s&.strip
1197
+ entry_workflow = entry["workflow"]&.to_s&.strip
1198
+ entry_source_skill = entry["source_skill"]&.to_s&.strip
1199
+ entry_skill = entry["skill"]&.to_s&.strip
1200
+
1201
+ next true if entry_source == source || entry_workflow == source
1202
+ next true if !source_skill.to_s.empty? && (entry_source_skill == source_skill || entry_skill == source_skill)
1203
+
1204
+ false
1205
+ end
1206
+ end
1207
+
1122
1208
  # Load step catalog from project override or gem defaults.
1123
1209
  #
1124
1210
  # @return [Array<Hash>] Loaded step definitions
1125
1211
  def step_catalog
1126
- @step_catalog ||= begin
1127
- project_root = Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
1128
- gem_root = Gem.loaded_specs["ace-assign"]&.gem_dir || File.expand_path("../../../..", __dir__)
1212
+ return @step_catalog if @step_catalog_loaded
1129
1213
 
1130
- project_catalog = File.join(project_root, ".ace", "assign", "catalog", "steps")
1131
- default_catalog = File.join(gem_root, ".ace-defaults", "assign", "catalog", "steps")
1214
+ if @step_catalog_from_fixture_set
1215
+ @step_catalog_loaded = true
1216
+ @step_catalog = @step_catalog_from_fixture
1217
+ return @step_catalog
1218
+ end
1132
1219
 
1133
- default_steps = Atoms::CatalogLoader.load_all(default_catalog)
1134
- base_catalog = if File.directory?(project_catalog)
1135
- project_steps = Atoms::CatalogLoader.load_all(project_catalog)
1136
- merge_step_catalog(default_steps, project_steps)
1137
- else
1138
- default_steps
1139
- end
1220
+ cached = self.class.send(:cached_value, :step_catalog_cache, step_catalog_signature)
1221
+ return @step_catalog = cached if cached
1222
+
1223
+ @step_catalog_loaded = true
1224
+ @step_catalog = load_step_catalog
1225
+ self.class.send(:store_cached_value, :step_catalog_cache, step_catalog_signature, @step_catalog)
1226
+ @step_catalog
1227
+ end
1228
+
1229
+ def step_catalog_signature
1230
+ [
1231
+ PROJECT_ROOT_SIGNAL,
1232
+ project_catalog_signature,
1233
+ default_catalog_signature,
1234
+ step_catalog_cache_token,
1235
+ CATALOG_SIGNAL
1236
+ ].join("|")
1237
+ end
1238
+
1239
+ def project_catalog_signature
1240
+ @project_catalog_signature ||= catalog_signature(File.join(project_root, ".ace", "assign", "catalog", "steps"))
1241
+ end
1242
+
1243
+ def default_catalog_signature
1244
+ @default_catalog_signature ||= catalog_signature(File.join(gem_root, ".ace-defaults", "assign", "catalog", "steps"))
1245
+ end
1246
+
1247
+ def load_step_catalog
1248
+ project_catalog = File.join(project_root, ".ace", "assign", "catalog", "steps")
1249
+ default_catalog = File.join(gem_root, ".ace-defaults", "assign", "catalog", "steps")
1250
+
1251
+ canonical_steps = @skill_source_resolver.assign_step_catalog
1252
+ default_steps = Atoms::CatalogLoader.load_all(default_catalog, canonical_steps: false)
1253
+ base_catalog = merge_step_catalog(default_steps, canonical_steps)
1254
+
1255
+ if File.directory?(project_catalog)
1256
+ project_steps = Atoms::CatalogLoader.load_all(project_catalog, canonical_steps: false)
1257
+ merge_step_catalog(base_catalog, project_steps)
1258
+ else
1259
+ base_catalog
1260
+ end
1261
+ end
1262
+
1263
+ def catalog_signature(catalog_dir)
1264
+ return "missing" unless File.directory?(catalog_dir)
1140
1265
 
1141
- canonical_steps = skill_source_resolver.assign_step_catalog
1142
- merge_step_catalog(base_catalog, canonical_steps)
1266
+ Dir.glob(File.join(catalog_dir, "*.step.yml")).sort.map do |path|
1267
+ "#{path}:#{file_signature(path)}"
1268
+ end.join("|")
1269
+ end
1270
+
1271
+ def file_signature(path)
1272
+ stat = File.stat(path)
1273
+ "#{stat.mtime.to_f}:#{stat.size}"
1274
+ rescue
1275
+ "missing"
1276
+ end
1277
+
1278
+ def step_catalog_cache_token
1279
+ token = if @skill_source_resolver.respond_to?(:cache_signature)
1280
+ @skill_source_resolver.cache_signature
1281
+ else
1282
+ "resolver:#{@skill_source_resolver.object_id}"
1143
1283
  end
1284
+
1285
+ "resolver:#{token}"
1286
+ end
1287
+
1288
+ def project_root
1289
+ @project_root ||= Ace::Support::Fs::Molecules::ProjectRootFinder.find_or_current
1290
+ end
1291
+
1292
+ def gem_root
1293
+ @gem_root ||= Gem.loaded_specs["ace-assign"]&.gem_dir || File.expand_path("../../../..", __dir__)
1144
1294
  end
1145
1295
 
1146
1296
  # Merge default and project step catalogs by step name.
@@ -1178,6 +1328,11 @@ module Ace
1178
1328
 
1179
1329
  merged = base.dup
1180
1330
  override.each do |key, value|
1331
+ if runtime_binding_override_key?(key, base, override)
1332
+ merged[key] = base[key]
1333
+ next
1334
+ end
1335
+
1181
1336
  merged[key] =
1182
1337
  if merged[key].is_a?(Hash) && value.is_a?(Hash)
1183
1338
  deep_merge_step_definition(merged[key], value)
@@ -1188,6 +1343,33 @@ module Ace
1188
1343
  merged
1189
1344
  end
1190
1345
 
1346
+ def runtime_binding_override_key?(key, base, override)
1347
+ return false unless %w[source workflow skill source_skill].include?(key)
1348
+ return false unless local_runtime_binding_present?(base)
1349
+ canonical_binding_present?(override)
1350
+ end
1351
+
1352
+ def local_runtime_binding_present?(entry)
1353
+ entry.is_a?(Hash) && (
1354
+ present_string?(entry["source"]) ||
1355
+ present_string?(entry["workflow"]) ||
1356
+ present_string?(entry["skill"])
1357
+ )
1358
+ end
1359
+
1360
+ def canonical_binding_present?(entry)
1361
+ entry.is_a?(Hash) && (
1362
+ present_string?(entry["source"]) ||
1363
+ present_string?(entry["workflow"]) ||
1364
+ present_string?(entry["skill"]) ||
1365
+ present_string?(entry["source_skill"])
1366
+ )
1367
+ end
1368
+
1369
+ def present_string?(value)
1370
+ value.is_a?(String) && !value.strip.empty?
1371
+ end
1372
+
1191
1373
  # Archive source config into the task's jobs/ directory.
1192
1374
  # If config is already in a jobs/ or steps/ directory, keeps it in place.
1193
1375
  # Otherwise moves job.yaml to <task>/jobs/<assignment_id>-job.yml for provenance.
@@ -1281,10 +1463,27 @@ module Ace
1281
1463
  def canonical_batch_insert_requested?(step_config)
1282
1464
  raw_sub_steps = step_config["sub_steps"] || step_config["sub-steps"]
1283
1465
  has_declared_sub_steps = raw_sub_steps.is_a?(Array) && raw_sub_steps.any?
1466
+ has_source = !step_config["source"].to_s.strip.empty?
1284
1467
  has_workflow = !step_config["workflow"].to_s.strip.empty?
1285
1468
  has_skill = !step_config["skill"].to_s.strip.empty?
1286
1469
 
1287
- has_declared_sub_steps || has_workflow || has_skill
1470
+ has_declared_sub_steps || has_source || has_workflow || has_skill
1471
+ end
1472
+
1473
+ def resolved_step_source(step, rendering)
1474
+ explicit_source = step["source"]&.to_s&.strip
1475
+ return explicit_source unless explicit_source.nil? || explicit_source.empty?
1476
+
1477
+ rendered_source = rendering["source"]&.to_s&.strip
1478
+ return rendered_source unless rendered_source.nil? || rendered_source.empty?
1479
+
1480
+ workflow_source = rendering["workflow"]&.to_s&.strip
1481
+ return workflow_source unless workflow_source.nil? || workflow_source.empty?
1482
+
1483
+ skill_name = rendering["skill"]&.to_s&.strip
1484
+ return nil if skill_name.nil? || skill_name.empty?
1485
+
1486
+ "skill://#{skill_name}"
1288
1487
  end
1289
1488
 
1290
1489
  def insert_canonical_batch_step_tree(step_config, after:, as_child:, added_by:, location:)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ace
4
4
  module Assign
5
- VERSION = "0.42.4"
5
+ VERSION = '0.53.4'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-assign
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.42.4
4
+ version: 0.53.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-04-05 00:00:00.000000000 Z
10
+ date: 2026-04-20 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-support-cli
@@ -99,14 +99,14 @@ dependencies:
99
99
  requirements:
100
100
  - - "~>"
101
101
  - !ruby/object:Gem::Version
102
- version: '0.30'
102
+ version: '0.34'
103
103
  type: :runtime
104
104
  prerelease: false
105
105
  version_requirements: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '0.30'
109
+ version: '0.34'
110
110
  - !ruby/object:Gem::Dependency
111
111
  name: ace-task
112
112
  requirement: !ruby/object:Gem::Requirement
@@ -206,7 +206,6 @@ files:
206
206
  - ".ace-defaults/assign/catalog/steps/task-load.step.yml"
207
207
  - ".ace-defaults/assign/catalog/steps/update-docs.step.yml"
208
208
  - ".ace-defaults/assign/catalog/steps/update-pr-desc.step.yml"
209
- - ".ace-defaults/assign/catalog/steps/verify-e2e.step.yml"
210
209
  - ".ace-defaults/assign/catalog/steps/verify-test-suite.step.yml"
211
210
  - ".ace-defaults/assign/catalog/steps/verify-test.step.yml"
212
211
  - ".ace-defaults/assign/catalog/steps/work-on-task.step.yml"
@@ -221,6 +220,11 @@ files:
221
220
  - CHANGELOG.md
222
221
  - README.md
223
222
  - Rakefile
223
+ - docs/demo/canonical-skill-source.gif
224
+ - docs/demo/canonical-skill-source.tape.yml
225
+ - docs/demo/fork-provider.cast
226
+ - docs/demo/fork-provider.gif
227
+ - docs/demo/fork-provider.recording.json
224
228
  - docs/demo/fork-provider.tape.yml
225
229
  - docs/exit-codes.md
226
230
  - docs/getting-started.md
@@ -236,14 +240,23 @@ files:
236
240
  - handbook/skills/as-assign-recover-fork/SKILL.md
237
241
  - handbook/skills/as-assign-run-in-batches/SKILL.md
238
242
  - handbook/skills/as-assign-start/SKILL.md
243
+ - handbook/skills/as-create-retro-internal/SKILL.md
244
+ - handbook/skills/as-mark-task-done-internal/SKILL.md
245
+ - handbook/skills/as-reflect-and-refactor-internal/SKILL.md
246
+ - handbook/skills/as-task-load-internal/SKILL.md
239
247
  - handbook/workflow-instructions/assign/add-task.wf.md
240
248
  - handbook/workflow-instructions/assign/compose.wf.md
249
+ - handbook/workflow-instructions/assign/create-retro-internal.wf.md
241
250
  - handbook/workflow-instructions/assign/create.wf.md
242
251
  - handbook/workflow-instructions/assign/drive.wf.md
252
+ - handbook/workflow-instructions/assign/mark-task-done-internal.wf.md
243
253
  - handbook/workflow-instructions/assign/prepare.wf.md
244
254
  - handbook/workflow-instructions/assign/recover-fork.wf.md
255
+ - handbook/workflow-instructions/assign/reflect-and-refactor-internal.wf.md
245
256
  - handbook/workflow-instructions/assign/run-in-batches.wf.md
246
257
  - handbook/workflow-instructions/assign/start.wf.md
258
+ - handbook/workflow-instructions/assign/task-load-internal.wf.md
259
+ - handbook/workflow-instructions/assign/verify-test-suite.wf.md
247
260
  - lib/ace/assign.rb
248
261
  - lib/ace/assign/atoms/assign_frontmatter_parser.rb
249
262
  - lib/ace/assign/atoms/catalog_loader.rb
@@ -263,11 +276,13 @@ files:
263
276
  - lib/ace/assign/cli/commands/fail.rb
264
277
  - lib/ace/assign/cli/commands/finish.rb
265
278
  - lib/ace/assign/cli/commands/fork_run.rb
279
+ - lib/ace/assign/cli/commands/fork_session.rb
266
280
  - lib/ace/assign/cli/commands/list.rb
267
281
  - lib/ace/assign/cli/commands/retry_cmd.rb
268
282
  - lib/ace/assign/cli/commands/select.rb
269
283
  - lib/ace/assign/cli/commands/start.rb
270
284
  - lib/ace/assign/cli/commands/status.rb
285
+ - lib/ace/assign/cli/commands/step.rb
271
286
  - lib/ace/assign/models/assignment.rb
272
287
  - lib/ace/assign/models/assignment_info.rb
273
288
  - lib/ace/assign/models/queue_state.rb
@@ -280,6 +295,7 @@ files:
280
295
  - lib/ace/assign/molecules/skill_assign_source_resolver.rb
281
296
  - lib/ace/assign/molecules/step_renumberer.rb
282
297
  - lib/ace/assign/molecules/step_writer.rb
298
+ - lib/ace/assign/molecules/tmux_fork_runner.rb
283
299
  - lib/ace/assign/organisms/assignment_executor.rb
284
300
  - lib/ace/assign/organisms/task_assignment_creator.rb
285
301
  - lib/ace/assign/version.rb
@@ -1,42 +0,0 @@
1
- name: verify-e2e
2
- skill: as-e2e-review
3
- render: step_template
4
- description: Review E2E coverage for modified packages and run targeted scenarios
5
-
6
- prerequisites:
7
- - name: work-on-task
8
- strength: required
9
- reason: "Must have implementation to test"
10
- - name: verify-test-suite
11
- strength: recommended
12
- reason: "Unit tests should pass before running E2E"
13
-
14
- produces: [e2e-results, coverage-matrix]
15
- consumes: [code-changes]
16
-
17
- context:
18
- default: null
19
- reason: "E2E review and execution run in the project environment"
20
-
21
- when_to_skip:
22
- - "No public CLI API changes (internal-only refactoring)"
23
- - "Package has no E2E test scenarios and no coverage gaps identified"
24
- - "All modified files are docs-only (*.md, *.yml non-config, task specs, retros)"
25
-
26
- effort: medium
27
- tags: [testing, e2e, verification]
28
-
29
- steps:
30
- - name: review-coverage
31
- description: "Run /as-e2e-review for each heavily modified package to get coverage matrix"
32
- tool: "ace-e2e-review <package>"
33
- note: "Identify gaps, overlaps, and which TCs need updating before running"
34
-
35
- - name: update-if-needed
36
- description: "If coverage matrix shows gaps or stale TCs, update or create E2E tests"
37
- conditional: "coverage-matrix shows gaps or outdated TCs"
38
-
39
- - name: run-targeted
40
- description: "Run ace-test-e2e-suite for each heavily modified package (not full suite)"
41
- tool: "ace-test-e2e-suite <package>"
42
- note: "Pass package name(s) of heavily modified packages only"