space-architect 5.5.1 → 7.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 71935f28a32069832af5b4d25f368d33c7efc505267a98c4f4b49f75a0084861
4
- data.tar.gz: 2b067fdbdd5a950b204ef9fb16a3484a634e0b6acd2f9ca467e8f47adec29902
3
+ metadata.gz: 1d521b0afec00484bfba5b35e26e9f0a603807fb75f3569fa61b0a0b5ff9b3ab
4
+ data.tar.gz: d21ecd2d8dd8458b0ec2e89d4cc2ee45a5a70eafc53955b8d2b3c365b55efe3b
5
5
  SHA512:
6
- metadata.gz: 66a47fc8027809c4132ba9e5365694ab530d646be68b0cacec80d527e81dcb28f7d192afb4e76ea1e9b0489bada20013af2c32da066075e28f39bb407fc89243
7
- data.tar.gz: f10a02847f4dafb408b98eb6a79f4b911bc0db7bf1856fbef18b751928f2e824ee5a5596db82ca94641f2fa5f55b037a671d9fed4daf0c8b54a374735b5d4baf
6
+ metadata.gz: e27a4154359d6f41370287eb86eeb2881d415dd0ce7e5d6c3c3f241ff338f168a7393456d63faa5e3970e3a72eb927ae4db13d4f407e50e320d90ed54c79dc7e
7
+ data.tar.gz: 024047dcd39a0de008284fc256c3f7fb08ea8585e0cd0cae53f0e990b70f9e47341325cf92668ef632bf76ef2e34e5d082ccd98eba94af52c4f659c251afd9f8
data/CHANGELOG.md CHANGED
@@ -5,6 +5,199 @@ 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
+ ## [7.0.0] - 2026-08-14
9
+
10
+ Three iterations of the Architect Loop run against this repo's own tooling, each
11
+ frozen before dispatch and judged by a separate session against criteria written
12
+ before results existed. Major because three destructive verbs gain a refusal they
13
+ did not have, and `provision`'s per-lane return changes shape — see the
14
+ **BREAKING** items under Changed.
15
+
16
+ Every defect closed here is the same animal: a **confident, wrong artifact**. An
17
+ operation that destroys a completed builder run and exits 0 reporting success. A
18
+ value the tool resolves correctly and then declines to use. A lane denied the tool
19
+ it needed, which does not crash and instead files a well-formatted, dataless
20
+ report. The through-line is that none of them announced itself — which is why the
21
+ fixes are as much about making the resolved value *visible* as about resolving it.
22
+ Suite: 1297 → 1344 runs, 5148 → 5373 assertions, green throughout.
23
+
24
+ ### Added
25
+
26
+ - **`--allowed-tools` / `--append-allowed-tools` on `architect dispatch`, and
27
+ `allowed_tools:` / `append_allowed_tools:` on the frozen lane declaration
28
+ (#89).** `ClaudeCodeHarness::ALLOWED_TOOLS` was a defaulted keyword that
29
+ `Harness.for` never accepted and no caller could pass, so no dispatched lane
30
+ could be granted an MCP tool. Because `claude -p` **denies** an unlisted tool
31
+ rather than prompting, the lane did not fail — it reasoned its way to "I was
32
+ unable to query the datasource" and wrote a plausible empty report. Replace and
33
+ append compose as one rule regardless of which surface supplied them
34
+ (`ClaudeCodeHarness.resolve_tools`); the CLI flag wins over the lane key **on
35
+ the same axis**, so a lane's `allowed_tools:` still supplies the base a
36
+ `--append-allowed-tools` flag appends to. The yaml half lives in the frozen lane
37
+ declaration so a grant is reviewable and judged like every other lane boundary
38
+ rather than buried in a shell invocation, and it survives worktree
39
+ re-materialization by the same mechanism `touch_set` already uses.
40
+ - **The resolved grant is recorded and surfaced.** Stamped onto the lane beside
41
+ `harness`/`model`/`effort`, printed at dispatch with its provenance (which
42
+ surface won), and shown in `architect status`'s lane line when it diverges from
43
+ the default. A denial now traces back to a grant a human can read. An MCP
44
+ *reachability* probe is deliberately not in this release: there is no MCP
45
+ modelling anywhere in the codebase, and a prober is a subsystem, not a rider on
46
+ a plumbing fix.
47
+
48
+ ### Changed
49
+
50
+ - **BREAKING — `architect worktree remove`, `architect integrate --teardown`, and
51
+ `architect provision --base` refuse to discard a lane worktree's uncommitted
52
+ work.** The existing safety checks asked whether work had been *committed*, in a
53
+ system whose hard rule 7 guarantees lane work is **never** committed — so all
54
+ three destroyed completed builder runs and exited 0 reporting success. One
55
+ predicate (`dirty_file_count`, untracked files included) now guards all three
56
+ sites. `--force` overrides and discards, restoring the old behavior exactly. A
57
+ script that tore down dirty lanes will now exit non-zero.
58
+ - **BREAKING — the multi-lane verbs decide their refusal before mutating
59
+ anything.** `integrate --teardown` and `provision --base` pre-flight the whole
60
+ declared lane set (`refuse_teardown_if_dirty!`, `refuse_repoint_if_dirty!`), so a
61
+ dirty lane discovered late no longer leaves earlier lanes already destroyed. The
62
+ refusal names every offending lane at once instead of failing on the first.
63
+ - **BREAKING — `provision`'s per-lane return is now `outcome:`**
64
+ (`:created` / `:unchanged` / `:repointed`) plus `discarded:`, replacing the
65
+ boolean `created:`. The boolean could not express the re-point path that #88's
66
+ fix introduces.
67
+ - **`worktree add`, `worktree list`, and `worktree remove` accept an optional
68
+ trailing `SPACE` argument**, like every other space-scoped verb. `worktree
69
+ remove` previously had no way to name its space and resolved from `$PWD` — a
70
+ destructive verb that could fire against the wrong space entirely.
71
+ - **Long-running lane guidance in `skill/architect/dispatch.md` (#85).** The lane
72
+ template's no-busy-wait clause beat every attempt to hold a 30–70 minute detached
73
+ process open, killing exactly the lanes it was least safe to kill.
74
+
75
+ ### Fixed
76
+
77
+ - **`architect provision --base` was resolved and then discarded on the re-attach
78
+ path (#88).** `worktree_add` computed `base_sha` from `--base`, ignored it when
79
+ the lane branch already existed, and recorded it anyway — so `space.yaml` claimed
80
+ a base the worktree was never pointed at. An operator-supplied `--base` is now
81
+ enforced (re-point, or refuse when that would discard work); an internal
82
+ re-materialization still reattaches at whatever is there, never refusing and never
83
+ moving a branch nobody asked to move.
84
+ - **`architect rehearse` refused every cross-repo iteration (#90).** It resolved one
85
+ repo for the whole iteration and raised when the drafted lanes named more than
86
+ one, even though `execute_gates` could already resolve a run dir per gate. Gates
87
+ carrying their own `cwd` now rehearse in their own declared directory regardless
88
+ of how many repos the iteration spans; the refusal survives only for gates that
89
+ genuinely need a default, and it names them.
90
+
91
+ ## [6.0.0] - 2026-08-03
92
+
93
+ Twelve iterations of the Architect Loop run against this repo's own tooling, each
94
+ frozen before dispatch and judged by a separate session against criteria written
95
+ before results existed. Major because `architect freeze` gains two hard
96
+ preconditions it did not have — see the **BREAKING** items under Changed.
97
+
98
+ Roughly half the release is machinery that stops the next papercut being written:
99
+ gates you can execute *before* freezing them, lane boundaries that cannot silently
100
+ disagree with themselves, and an escape valve for the case where the frozen
101
+ contract is the thing that is wrong. Suite: 1212 → 1297 runs, 4811 → 5148
102
+ assertions, green throughout, with the last known flake causally explained rather
103
+ than retried away.
104
+
105
+ ### Added
106
+
107
+ - **`architect rehearse ITERATION`** — the phase between authoring and freeze
108
+ (#81, consolidating #73, #39, #34). Runs the *drafted* (unfrozen, working-tree)
109
+ gates through the identical execution path `architect gate` uses — `execute_gates`
110
+ is extracted byte-for-byte, so the two can never diverge — and classifies each
111
+ RED / GREEN / BROKEN / EMPTY. Prints the resolved `dir` that was always in the
112
+ result hash and never rendered. `--record` emits a paste-able provenance block
113
+ for the iteration's AC preamble.
114
+ - **Scope-asymmetry reporting in `rehearse`** — for each gate whose command is a
115
+ recognizable file-scoped grep invocation, the gate's own pattern is re-run across
116
+ the whole repo via `git grep` and anything matching outside the gate's declared
117
+ paths is named, loudest when it also falls outside every declared lane's touch
118
+ set. Catches the failure mode where a boundary is stated consistently in three
119
+ places and is wrong in all three because all three were drawn from one too-narrow
120
+ grep. Reports only: it never touches `rehearse`'s exit code, its RED/GREEN/BROKEN
121
+ classification, or the rehearsal stamp. An invocation carrying a flag `git grep`
122
+ has no equivalent for (`-x`) is declined by name and counted as not-analyzed
123
+ rather than answered wrong.
124
+ - **`architect integrate --accept-bounds REASON`** — merges a lane that wrote
125
+ outside its declared touch set when the *declaration* is the defect and the freeze
126
+ rules correctly forbid widening it after the fact. Recorded per-lane in
127
+ `space.yaml` against the lane that was actually out of bounds, never silently, and
128
+ never able to override the no-builder-commits check.
129
+ - **`architect freeze --skip-rehearse REASON`** — the deliberate escape from the new
130
+ rehearsal precondition, with the reason recorded in `space.yaml`. An empty REASON
131
+ is refused.
132
+ - **`Space::Core::Paths` glob helpers** — one documented decision about when a
133
+ content-tree glob includes dotfiles, guarded by `test/paths_guard_test.rb` so the
134
+ flags cannot drift apart again across call sites.
135
+
136
+ ### Changed
137
+
138
+ - **BREAKING — `architect freeze` requires a fresh rehearsal stamp.** The stamp is
139
+ digest-keyed to the gates block, so editing one byte of a gate after rehearsing
140
+ invalidates it; it records that the architect *looked*, never that the gates
141
+ passed. An iteration that froze cleanly on 5.x now errors with
142
+ `has not been rehearsed against its current gates`. Run `architect rehearse
143
+ ITERATION` first, or `architect freeze ITERATION --skip-rehearse REASON` to skip
144
+ deliberately.
145
+ - **BREAKING — `architect freeze` refuses an untouched scaffold placeholder.** An
146
+ Acceptance Criteria section still carrying the template's placeholder AC1 with no
147
+ active gate is now an error rather than a successful freeze (#73). Narrow by
148
+ design: a hand-authored prose-only AC without the placeholder still freezes, so
149
+ the spike path the skill sanctions is untouched.
150
+ - **`architect integrate` commits its own `space.yaml` mutation.** It previously
151
+ wrote `integration_branch`/`integrate_sha` to disk and deferred the commit to
152
+ whatever committing command ran next, leaving a window in which a dying session
153
+ lost the record of which lanes had merged — which happened, and cost a full
154
+ judging session. The commit is made by pathspec so unrelated dirty files are not
155
+ swept in, once per call rather than once per lane, and from an `ensure` so a merge
156
+ conflict partway through the lane set still preserves what already merged.
157
+ - **`architect evidence` replaces a lane's subsection instead of appending.**
158
+ Re-transcribing a corrected report no longer leaves both copies in Builder Report.
159
+ - **Gate commands are spawned through an explicit `/bin/sh -c`**, so the documented
160
+ shell is the actual shell regardless of the invoking environment.
161
+ - **Skill prose (`skill/architect/`, `docs/DESIGN.md`).** The lane-prompt template
162
+ tells builders not to title their scratch report (the CLI supplies the `### <lane>`
163
+ heading) and to keep internal headings at `###` or deeper; `SKILL.md` §4 carries
164
+ the boundary-enumeration discipline and the content rule that a criterion renaming
165
+ an identifier must be drawn from a whole-repo grep, not `lib/` alone. These are
166
+ load-bearing: lane prompts are assembled from `dispatch.md`, and at least one
167
+ defect in this release was caused by prose and code disagreeing.
168
+
169
+ ### Fixed
170
+
171
+ - **`architect research dispatch` silently launched only the first prompt (#83).**
172
+ Given five prompt paths it launched one, exited 0, and printed nothing on stderr —
173
+ destroying evidence the architect then writes research grounds from. dry-cli binds
174
+ only the first positional to a scalar `argument` and drops the rest into the
175
+ options hash; `Supervisor#dispatch` had always handled an array correctly. Fixed
176
+ with dry-cli's own `type: :array`, the established idiom at
177
+ `space_src/cli/clone.rb:19`. Net −1 line.
178
+ - **`architect bug-report` buried the title in an HTML comment `gh` ignores (#41)**,
179
+ forcing a manual `--title` on every filing.
180
+ - **The dispatch liveness check was a point-sample race in production**, not only in
181
+ tests. It now waits for a real stream-json init event and reports true elapsed
182
+ time, and scans the run log incrementally instead of re-parsing it from the top
183
+ every 50ms — 92.6MB → 615KB of reads over a 300-poll worst case.
184
+ - **`Commands.wrap`'s quote scanner was not backslash-aware.** Verified at the
185
+ property level with `bash` as the oracle over an eight-command battery, rather than
186
+ by adding another example.
187
+ - **`Dir.glob` calls silently skipped dotfiles** in `SkillInstaller.same_content?`
188
+ and its siblings; consolidated behind the new `Space::Core::Paths` decision.
189
+ - **The last suite flake, explained rather than retried.** `FileUtils.cp_r` of the
190
+ git fixture templates raced `git maintenance --detach`, which outlived `system()`
191
+ and mutated `.git/objects/` mid-copy. Stress: 13/24 failures → 0/24, twice.
192
+ - **A clone-concurrency test's fiber rendezvous was unbounded** — correct only by an
193
+ accident of `Async::Task#async`'s greedy dispatch, and would have hung `rake test`
194
+ forever with no message if scheduling ever shifted. Now bounded, failing legibly
195
+ while keeping the exact peak-concurrency assertion it was written for.
196
+ - **The scope-asymmetry check overstated its own certainty.** It replayed a gate's
197
+ pattern but dropped the gate's `-w`, so the whole-repo re-run was *broader* than
198
+ the gate it stood in for and printed the surplus under its loudest line ("no lane
199
+ may legally fix these"). `-w` is now replayed and `-x` declined by name.
200
+
8
201
  ## [5.5.1] - 2026-07-25
9
202
 
10
203
  ### Fixed