ace-support-config 0.16.3 → 0.17.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 292cd8b30cde0ff6e42674342eec91c5ced9ac82e54721c41889e2efce28c0b2
4
- data.tar.gz: bc74b84b53654b33d26b737236066c9d4699cda31dce60a4950f68116cccf4b9
3
+ metadata.gz: 1f7f5cddbf50a8da6f9f42cc644f193cd9a2898757a3417849fc4104546c8ba2
4
+ data.tar.gz: 54c887961b4c3473a7a4be0bc5383b2ab4975d2d779c86e98c02e180a298c082
5
5
  SHA512:
6
- metadata.gz: a0f53f807d5dd5660e9e66b429975a52f3b03d8aa3ff50a5bfe2bbfc064d268873affdd9e6c046942e93aaec4f6805803507d78083aea8ab9a8cd60a35b88181
7
- data.tar.gz: 955386f488b292bd9eaadb0c0e30324628c0d7022f1bc86a1ac680296a067d720977262d194b5d5963b4098525c094e6c915361bb0abf7a43432b214f4e07c6f
6
+ metadata.gz: 5a3291da675776cd51aa9f5d888bc8f001c3f0221206c684551ec0bfaa3cbdfe94361ed3c8a56826bce3cd838a172873cdf31afa95202a4ea0dc6278afce111d
7
+ data.tar.gz: 570b40415d3a4b63b3762d09fea0b43c74628dd91f286818215aaa388371d26dc586f4ab00316b6c781ae38e1555477cf07a03d0340fa2e4f8d1b9ec7b0463a9
data/CHANGELOG.md CHANGED
@@ -7,9 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.17.1] - 2026-06-30
11
+
12
+ ### Changed
13
+ - Updated `ace-config doctor` skill projection health to ignore disabled provider projections reported by `ace-handbook status`.
14
+
15
+ ## [0.17.0] - 2026-06-30
16
+
17
+ ### Added
18
+ - Added `ace-config doctor` warnings for projects whose root agent guidance or `docs/tools.md` are missing generated agent-engineering guidance markers.
19
+
10
20
  ### Fixed
11
21
  - Corrected `ace-config-bootstrap-root-files` to sync `ace-support-core` and record from the sandbox root layout where the bootstrap files are actually created.
12
22
 
23
+ ### Technical
24
+ - Expanded bootstrap sync coverage for generated `docs/tools.md`, cost-bias markers, preservation without `--force`, force refresh, and subdirectory root targeting.
25
+
13
26
  ## [0.16.2] - 2026-04-24
14
27
 
15
28
  ### Technical
@@ -28,6 +28,12 @@ module Ace
28
28
  CORE_ROLES = %w[commit doctor].freeze
29
29
  UTILITY_ROLE_GROUPS = %w[_utility _utility-lite].freeze
30
30
  ROLE_REFERENCE_PATTERN = /\brole:([A-Za-z0-9_-]+)\b/
31
+ COST_BIAS_MARKER = "Cost Bias Override"
32
+ AGENT_ENGINEERING_ANCHOR = "docs/tools.md#agent-engineering-practices"
33
+ AGENT_ENGINEERING_HEADING = "## Agent Engineering Practices"
34
+ AGENT_ENGINEERING_NEXT_ACTION = "Run ace-config sync ace-support-core --force in generated projects, " \
35
+ "or manually add the Cost Bias Override line and docs/tools.md Agent Engineering Practices section " \
36
+ "in customized projects."
31
37
 
32
38
  def run(json: false, no_probe: false, probe: false, hygiene: false, verbose: false, colors: true, quiet: false, io: $stdout)
33
39
  started_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -43,6 +49,7 @@ module Ace
43
49
  append_check(checks, discovery_check, stream: stream, io: io)
44
50
 
45
51
  append_check(checks, check_config_defaults, stream: stream, io: io)
52
+ append_check(checks, check_agent_engineering_guidance, stream: stream, io: io)
46
53
 
47
54
  provider_context = load_provider_context if package_check[:status] != BLOCKER
48
55
 
@@ -173,6 +180,68 @@ module Ace
173
180
  )
174
181
  end
175
182
 
183
+ def check_agent_engineering_guidance
184
+ root = project_root
185
+ root_guidance_paths = %w[AGENTS.md CLAUDE.md].map { |name| File.join(root, name) }
186
+ docs_path = File.join(root, "docs", "tools.md")
187
+ existing_root_guidance = root_guidance_paths.select { |path| File.exist?(path) }
188
+ docs_content = File.exist?(docs_path) ? File.read(docs_path) : nil
189
+ guidance_contents = existing_root_guidance.to_h { |path| [path, File.read(path)] }
190
+
191
+ unless existing_root_guidance.any? || docs_content
192
+ return check(
193
+ id: "agent-engineering-guidance",
194
+ kind: "health",
195
+ status: PASS,
196
+ message: "Agent engineering guidance not installed"
197
+ )
198
+ end
199
+
200
+ findings = []
201
+ guidance_contents.each do |path, content|
202
+ next if content.include?(COST_BIAS_MARKER)
203
+
204
+ findings << "#{File.basename(path)} lacks #{COST_BIAS_MARKER}"
205
+ end
206
+
207
+ if docs_content.nil?
208
+ findings << "docs/tools.md is missing"
209
+ elsif !docs_content.include?(AGENT_ENGINEERING_HEADING)
210
+ findings << "docs/tools.md lacks #{AGENT_ENGINEERING_HEADING}"
211
+ end
212
+
213
+ if guidance_contents.values.any? { |content| content.include?(AGENT_ENGINEERING_ANCHOR) } &&
214
+ (!docs_content || !docs_content.include?(AGENT_ENGINEERING_HEADING))
215
+ findings << "root guidance links #{AGENT_ENGINEERING_ANCHOR} but the anchor target is absent"
216
+ end
217
+
218
+ if findings.empty?
219
+ return check(
220
+ id: "agent-engineering-guidance",
221
+ kind: "health",
222
+ status: PASS,
223
+ message: "Agent engineering guidance is present"
224
+ )
225
+ end
226
+
227
+ check(
228
+ id: "agent-engineering-guidance",
229
+ kind: "health",
230
+ status: WARN,
231
+ message: "Agent engineering guidance is incomplete",
232
+ next_action: AGENT_ENGINEERING_NEXT_ACTION,
233
+ details: findings.uniq
234
+ )
235
+ rescue => e
236
+ check(
237
+ id: "agent-engineering-guidance",
238
+ kind: "health",
239
+ status: WARN,
240
+ message: "Agent engineering guidance check failed: #{e.message}",
241
+ next_action: AGENT_ENGINEERING_NEXT_ACTION
242
+ )
243
+ end
244
+
176
245
  def check_skill_sync
177
246
  out, err, status = Open3.capture3("ace-handbook", "status", "--format", "json")
178
247
  unless status.success?
@@ -188,7 +257,8 @@ module Ace
188
257
 
189
258
  snapshot = JSON.parse(out)
190
259
  providers = Array(snapshot["providers"])
191
- drifted = providers.select do |entry|
260
+ checked_providers = providers.select { |entry| entry.fetch("enabled", true) }
261
+ drifted = checked_providers.select do |entry|
192
262
  entry.fetch("missing", 0).to_i.positive? ||
193
263
  entry.fetch("outdated", 0).to_i.positive? ||
194
264
  entry.fetch("extra", 0).to_i.positive?
@@ -200,8 +270,8 @@ module Ace
200
270
  id: "skill-sync",
201
271
  kind: "health",
202
272
  status: PASS,
203
- message: "Provider skills are in sync (#{providers.length} providers, #{total_skills} skills)",
204
- skill_sync: {providers: providers, canonical_total: total_skills}
273
+ message: "Provider skills are in sync (#{checked_providers.length} providers, #{total_skills} skills)",
274
+ skill_sync: {providers: checked_providers, canonical_total: total_skills}
205
275
  )
206
276
  end
207
277
 
@@ -209,10 +279,10 @@ module Ace
209
279
  id: "skill-sync",
210
280
  kind: "health",
211
281
  status: WARN,
212
- message: "Provider skill sync drift detected (#{drifted.length}/#{providers.length} providers)",
282
+ message: "Provider skill sync drift detected (#{drifted.length}/#{checked_providers.length} providers)",
213
283
  next_action: "Run ace-handbook sync to refresh provider-native skills.",
214
284
  details: drifted.map { |entry| skill_sync_detail(entry) },
215
- skill_sync: {providers: providers, drifted: drifted}
285
+ skill_sync: {providers: checked_providers, drifted: drifted}
216
286
  )
217
287
  rescue Errno::ENOENT
218
288
  check(
@@ -3,7 +3,7 @@
3
3
  module Ace
4
4
  module Support
5
5
  module Config
6
- VERSION = '0.16.3'
6
+ VERSION = '0.17.1'
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ace-support-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michal Czyz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2026-04-26 00:00:00.000000000 Z
10
+ date: 2026-06-30 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: ace-support-fs