space-architect 5.5.0 → 5.5.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: e170b3f69d5b2a6bdeb9422aedc341df20148e7085ea38b120b43508a9aaf3d0
4
- data.tar.gz: 8ed8737fdeacf88a4ef1917fcf2a695e3d7f6f679eb1c6745094179bf57a8166
3
+ metadata.gz: 71935f28a32069832af5b4d25f368d33c7efc505267a98c4f4b49f75a0084861
4
+ data.tar.gz: 2b067fdbdd5a950b204ef9fb16a3484a634e0b6acd2f9ca467e8f47adec29902
5
5
  SHA512:
6
- metadata.gz: '059f2419d80fc974f33c66367f9bc3a3c58492ed095d155c7e9aaa07c0c127ef374e236a973dd21c635e0c2eea97f62fafe83e66c03f8c3a6f5109f4745c20c3'
7
- data.tar.gz: 2ee62770684237d0f60eedc5e752695846ff9dfd95836876b555e94e68683bc1ec4367a2006ea35fb350313b568a1d81d6a13822dea4747364f4710688984002
6
+ metadata.gz: 66a47fc8027809c4132ba9e5365694ab530d646be68b0cacec80d527e81dcb28f7d192afb4e76ea1e9b0489bada20013af2c32da066075e28f39bb407fc89243
7
+ data.tar.gz: f10a02847f4dafb408b98eb6a79f4b911bc0db7bf1856fbef18b751928f2e824ee5a5596db82ca94641f2fa5f55b037a671d9fed4daf0c8b54a374735b5d4baf
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [5.5.1] - 2026-07-25
9
+
10
+ ### Fixed
11
+
12
+ - **Lane in-bounds check no longer false-FAILs on dotfile directories** — the
13
+ `touch_set` matcher built its `fnmatch` flags without `File::FNM_DOTMATCH`, so
14
+ a `dir/**` touch glob never matched a path with a dot-prefixed segment. Any
15
+ lane creating `.github/workflows/ci.yml` *inside its own declared directory*
16
+ was reported out-of-bounds by `architect verify` check (d) and hard-blocked by
17
+ `architect integrate` ("wrote outside its declared touch set"), with no
18
+ override — the touch set is frozen at spec time, so neither side of the
19
+ comparison could be adjusted legitimately and the merges had to be done by
20
+ hand. `merge_lane!`'s conflict classification carried the identical blind spot;
21
+ both sites now share one `in_touch_set?` predicate so the flags cannot drift
22
+ again.
23
+
8
24
  ## [5.5.0] - 2026-07-22
9
25
 
10
26
  ### Added
@@ -42,6 +42,13 @@ module Space::Architect
42
42
  # Hard per-gate timeout. Generous relative to the full suite (~55s).
43
43
  DEFAULT_GATE_TIMEOUT = 900
44
44
 
45
+ # Flags for matching a changed path against a lane's touch_set globs.
46
+ # PATHNAME keeps a single `*` from crossing `/`; EXTGLOB enables `{a,b}`;
47
+ # DOTMATCH lets a glob reach dotfile segments, so a `dir/**` touch set covers
48
+ # `dir/.github/workflows/ci.yml` — the standard deliverable for a lane preparing
49
+ # a directory to become a repo root.
50
+ TOUCH_FNM = File::FNM_PATHNAME | File::FNM_EXTGLOB | File::FNM_DOTMATCH
51
+
45
52
  # Legacy sentinel: worktree_add used to seed prompt.md with this placeholder
46
53
  # (dropped — the blind-overwrite tripped harness read-before-write guards, #48).
47
54
  # dispatch still refuses to launch on this content, so stubs in old spaces
@@ -404,10 +411,7 @@ module Space::Architect
404
411
  git_capture("-C", repo_path.to_s, "merge", "--abort")
405
412
  conflict_files = conflicts.split
406
413
  lane_touch_set = lane_entry["touch_set"] || []
407
- fnm = File::FNM_PATHNAME | File::FNM_EXTGLOB
408
- outside = conflict_files.reject do |f|
409
- lane_touch_set.any? { |g| File.fnmatch(g, f, fnm) || (g.end_with?("/**") && File.fnmatch("#{g}/*", f, fnm)) }
410
- end
414
+ outside = conflict_files.reject { |f| in_touch_set?(f, lane_touch_set) }
411
415
  if !lane_touch_set.empty? && outside.empty?
412
416
  raise Space::Core::Error,
413
417
  "Merge conflict integrating lane '#{lane}' (#{conflict_files.join(", ")}) — the lane plan was " \
@@ -1298,18 +1302,23 @@ module Space::Architect
1298
1302
  i += 1
1299
1303
  changed << orig if orig && !orig.empty?
1300
1304
  end
1301
- fnm = File::FNM_PATHNAME | File::FNM_EXTGLOB
1302
- changed.all? do |f|
1303
- touch_set.any? do |g|
1304
- File.fnmatch(g, f, fnm) ||
1305
- (g.end_with?("/**") && File.fnmatch("#{g}/*", f, fnm))
1306
- end
1307
- end
1305
+ changed.all? { |f| in_touch_set?(f, touch_set) }
1308
1306
  end
1309
1307
 
1310
1308
  checks
1311
1309
  end
1312
1310
 
1311
+ # Is a changed path inside a lane's declared touch set? Single-sourced so the
1312
+ # in-bounds check (d) and merge_lane!'s conflict classification can never drift.
1313
+ # A trailing `dir/**` is matched twice: bare (PATHNAME stops it at direct
1314
+ # children) and as `dir/**/*`, whose whole-component `**/` does cross `/`.
1315
+ def in_touch_set?(path, globs)
1316
+ globs.any? do |g|
1317
+ File.fnmatch(g, path, TOUCH_FNM) ||
1318
+ (g.end_with?("/**") && File.fnmatch("#{g}/*", path, TOUCH_FNM))
1319
+ end
1320
+ end
1321
+
1313
1322
  # Replace (or, with append:, extend) the body of a "## Heading" section, leaving
1314
1323
  # every other section byte-untouched. Append replaces a placeholder body (only a
1315
1324
  # template comment) the first time, then stacks subsections after it. A supplied
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Space
4
4
  module Core
5
- VERSION = "5.5.0"
5
+ VERSION = "5.5.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: space-architect
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.5.0
4
+ version: 5.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Jacobs