space-architect 8.0.0 โ 9.1.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 +4 -4
- data/CHANGELOG.md +54 -0
- data/README.md +39 -464
- data/lib/space_architect/architect_project.rb +90 -39
- data/lib/space_architect/bug_report.rb +2 -1
- data/lib/space_architect/cli/architect.rb +189 -11
- data/lib/space_architect/cli/research.rb +1 -1
- data/lib/space_architect/cli.rb +9 -14
- data/lib/space_architect/loop_cost.rb +592 -0
- data/lib/space_architect/research/supervisor.rb +9 -2
- data/lib/space_architect/routing.rb +149 -0
- data/lib/space_architect/session_sync/bin_path.rb +1 -1
- data/lib/space_architect/session_sync/cursor.rb +1 -1
- data/lib/space_architect/session_sync/plist.rb +1 -1
- data/lib/{space_core โ space_architect}/version.rb +2 -2
- data/lib/space_architect.rb +2 -1
- data/skill/architect/SKILL.md +3 -2
- data/skill/architect-vocabulary/SKILL.md +2 -2
- metadata +20 -177
- data/exe/space +0 -13
- data/exe/src +0 -13
- data/lib/space_architect/cli/space.rb +0 -29
- data/lib/space_architect/cli/src.rb +0 -38
- data/lib/space_core/atomic_write.rb +0 -21
- data/lib/space_core/cli/base_command.rb +0 -19
- data/lib/space_core/cli/build.rb +0 -27
- data/lib/space_core/cli/config.rb +0 -49
- data/lib/space_core/cli/current.rb +0 -16
- data/lib/space_core/cli/help.rb +0 -195
- data/lib/space_core/cli/helpers.rb +0 -115
- data/lib/space_core/cli/init.rb +0 -29
- data/lib/space_core/cli/list.rb +0 -24
- data/lib/space_core/cli/loop_status.rb +0 -47
- data/lib/space_core/cli/new.rb +0 -38
- data/lib/space_core/cli/pack.rb +0 -29
- data/lib/space_core/cli/path.rb +0 -16
- data/lib/space_core/cli/repeatable_options.rb +0 -84
- data/lib/space_core/cli/repo.rb +0 -76
- data/lib/space_core/cli/run.rb +0 -44
- data/lib/space_core/cli/shell.rb +0 -125
- data/lib/space_core/cli/show.rb +0 -21
- data/lib/space_core/cli/status.rb +0 -74
- data/lib/space_core/cli/use.rb +0 -17
- data/lib/space_core/cli.rb +0 -177
- data/lib/space_core/commands.rb +0 -51
- data/lib/space_core/config.rb +0 -152
- data/lib/space_core/errors.rb +0 -14
- data/lib/space_core/git_client.rb +0 -49
- data/lib/space_core/mise_client.rb +0 -37
- data/lib/space_core/oci_builder.rb +0 -56
- data/lib/space_core/oci_packer.rb +0 -103
- data/lib/space_core/oci_runner.rb +0 -89
- data/lib/space_core/paths.rb +0 -58
- data/lib/space_core/repo_reference.rb +0 -19
- data/lib/space_core/repo_resolver.rb +0 -167
- data/lib/space_core/shell_integration.rb +0 -438
- data/lib/space_core/slugger.rb +0 -16
- data/lib/space_core/space.rb +0 -174
- data/lib/space_core/space_store.rb +0 -319
- data/lib/space_core/state.rb +0 -86
- data/lib/space_core/templates/oci/dockerfile.erb +0 -73
- data/lib/space_core/templates/oci/dockerignore.erb +0 -17
- data/lib/space_core/templates/oci/entrypoint.sh.erb +0 -16
- data/lib/space_core/terminal.rb +0 -161
- data/lib/space_core/warnings.rb +0 -13
- data/lib/space_core/xdg.rb +0 -33
- data/lib/space_core.rb +0 -26
- data/lib/space_src/cli/clone.rb +0 -54
- data/lib/space_src/cli/config.rb +0 -65
- data/lib/space_src/cli/daemon.rb +0 -362
- data/lib/space_src/cli/options.rb +0 -21
- data/lib/space_src/cli/org.rb +0 -199
- data/lib/space_src/cli/repo.rb +0 -169
- data/lib/space_src/cli/shell.rb +0 -121
- data/lib/space_src/cli/status.rb +0 -75
- data/lib/space_src/cli/sync.rb +0 -161
- data/lib/space_src/cli.rb +0 -159
- data/lib/space_src/cloner.rb +0 -77
- data/lib/space_src/config/contract.rb +0 -54
- data/lib/space_src/config/duration.rb +0 -79
- data/lib/space_src/config/model.rb +0 -49
- data/lib/space_src/config/store.rb +0 -156
- data/lib/space_src/forge/client.rb +0 -31
- data/lib/space_src/forge/github.rb +0 -98
- data/lib/space_src/launchd/agent.rb +0 -195
- data/lib/space_src/launchd/plist.rb +0 -129
- data/lib/space_src/log_rotator.rb +0 -46
- data/lib/space_src/migration.rb +0 -43
- data/lib/space_src/nav.rb +0 -99
- data/lib/space_src/paths.rb +0 -72
- data/lib/space_src/scm/client.rb +0 -87
- data/lib/space_src/scm/git.rb +0 -232
- data/lib/space_src/scm/status.rb +0 -24
- data/lib/space_src/shell.rb +0 -90
- data/lib/space_src/shell_integration.rb +0 -321
- data/lib/space_src/state/lock.rb +0 -59
- data/lib/space_src/state/store.rb +0 -140
- data/lib/space_src/sync/engine.rb +0 -503
- data/lib/space_src/sync/repo_plan.rb +0 -215
- data/lib/space_src/sync/report.rb +0 -18
- data/lib/space_src/ui/interactive_reporter.rb +0 -280
- data/lib/space_src/ui/json_reporter.rb +0 -39
- data/lib/space_src/ui/mode.rb +0 -68
- data/lib/space_src/ui/plain_reporter.rb +0 -53
- data/lib/space_src/ui/reporter.rb +0 -48
- data/lib/space_src/version.rb +0 -7
- data/lib/space_src.rb +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c2dfa94f98278929ea382e4411856749de3af270511f60760ee4e3bed83daf53
|
|
4
|
+
data.tar.gz: 33c9bf994eafc772c67399876826b77f685a7ac9e3417f38b37054d853b5479b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2b7c099ff9ffc9b1cf6e37d48a687b2c08c4f2c0463ea5f1e77d156f214bdf9e4f5d0059e1be9fa1247de440c50ea091ffb933db5f02c3bb8e2d8d75ed0f3996
|
|
7
|
+
data.tar.gz: 5ce698b9ed448dbab61db46302c5f51f4e0bd850c8748c052131ffea4ef718326a3a4de47562092ba782dcfcfa042c6dedfe1c56675119b9ba2d98e29caf5f49
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,60 @@ 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
|
+
## [9.0.0] - 2026-10-09
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **The split: space-architect is now the Architect Loop only.** The monolith
|
|
13
|
+
carved the space tool and the evergreen engine into their own gems โ
|
|
14
|
+
**space-cadet** 9.0.0 (`Space::Core`, the `space` binary) and **repo-tender**
|
|
15
|
+
1.0.0 (`RepoTender`, the `repo-tender` binary with the deprecated `src`
|
|
16
|
+
shim) โ and this gem consumes them as libraries instead of vendoring them.
|
|
17
|
+
Dropped: the vendored `lib/space_core` / `lib/space_src` subtrees, the
|
|
18
|
+
`exe/space` and `exe/src` binaries, and the `architect space โฆ` / `architect
|
|
19
|
+
src โฆ` forwarder intercepts. `architect space โฆ` / `architect src โฆ` are now
|
|
20
|
+
ordinary unknown commands (dry-cli usage + non-zero exit) โ the `space`
|
|
21
|
+
binary comes from space-cadet and the `src` binary from repo-tender; re-point
|
|
22
|
+
8.x scripts and aliases accordingly.
|
|
23
|
+
- **Upgrading from 8.x:** `gem uninstall space-architect` first โ the 8.x gem's
|
|
24
|
+
`space` and `src` executables collide with the ones the new gems ship โ then
|
|
25
|
+
`gem install space-architect` (pulls space-cadet) and, for the session-sync
|
|
26
|
+
rail, `gem install repo-tender`. Config/state: space-cadet โฅ 9.1 migrates the
|
|
27
|
+
substrate's `config.yml`/`state.yml` from the old
|
|
28
|
+
`~/.config|state/space-architect/` dirs automatically on first run of either
|
|
29
|
+
`space` or `architect` (on 9.0.0, move them across by hand); the loop's own
|
|
30
|
+
session-sync cursor stays where it is.
|
|
31
|
+
- **Host-branded help header.** `architect --help`'s root header now brands
|
|
32
|
+
the loop (`architect 9.0.0 โ โฆ`) via space-cadet's product-name/version seam
|
|
33
|
+
instead of the substrate's identity โ hence the `space-cadet ~> 9.1`
|
|
34
|
+
dependency floor.
|
|
35
|
+
- **Own version line.** The loop's version is now
|
|
36
|
+
`Space::Architect::VERSION = "9.0.0"` (`lib/space_architect/version.rb`) โ
|
|
37
|
+
its first, decoupled from `Space::Core::VERSION`. The gemspec version,
|
|
38
|
+
`architect --version`, the bug-report diagnostics, and the bug-report command
|
|
39
|
+
footer all derive from the loop's own constant; the bug report additionally
|
|
40
|
+
lists `space-cadet: <version>` as a dependency diagnostic.
|
|
41
|
+
- **Dependency posture.** Hard dependency: `space-cadet ~> 9.0`. The declared
|
|
42
|
+
set shrank to what the loop itself requires (`async-http`, `async-process`,
|
|
43
|
+
`protocol-http`, `pastel`, `dry-cli`, `dry-monads`, `dry-validation` โ `xdg`,
|
|
44
|
+
`tty-cursor`, `dry-struct`/`dry-types`, and bare `async` were the vendored
|
|
45
|
+
trees' deps, not the loop's). repo-tender is deliberately **not** a gemspec
|
|
46
|
+
runtime dependency: the `sessions agent` launchd seam requires it lazily and,
|
|
47
|
+
when the gem is absent, fails with a short actionable error naming the fix
|
|
48
|
+
(`gem install repo-tender`) instead of a LoadError backtrace. The dev
|
|
49
|
+
Gemfile includes repo-tender so the suite exercises the real integration.
|
|
50
|
+
- **Tests and mutation subjects classified, not carried.** Tests whose subject
|
|
51
|
+
was the vendored tools' functionality (everything under `test/space_core/`
|
|
52
|
+
and `test/space_src/`, the forwarder tests, the space-tool surface,
|
|
53
|
+
shell-integration, slugger, repo-resolver, warnings) dropped with the code โ
|
|
54
|
+
their coverage lives in the two gems. Loop tests keep running against the
|
|
55
|
+
gem-served `Space::Core`; fixture setup routes through the gem's own CLI.
|
|
56
|
+
The `:mutant` task now subjects `Space::Architect::GateEvaluator` and
|
|
57
|
+
`Space::Architect::GateLint` only.
|
|
58
|
+
- **Docs and skills updated to the split reality** (README, command reference,
|
|
59
|
+
releasing guide, design doc, skills): one binary, two gem dependencies, no
|
|
60
|
+
forwarders or vendored subtrees.
|
|
61
|
+
|
|
8
62
|
## [8.0.0] - 2026-10-09
|
|
9
63
|
|
|
10
64
|
### Changed
|
data/README.md
CHANGED
|
@@ -2,481 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/space-architect)
|
|
4
4
|
|
|
5
|
-
> **
|
|
5
|
+
> **The Architect Loop โ structured judgment-and-build cycles for humans and their agents!** โจ๐ฐ๏ธ
|
|
6
6
|
|
|
7
|
-
`space-architect` is
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
`space-architect` is the gem behind the **Architect Loop**: a structured
|
|
8
|
+
judgment-and-build cycle in which a strong reasoning model (the *architect*)
|
|
9
|
+
plans, freezes acceptance criteria, and judges the work of a fleet of headless
|
|
10
|
+
AI *builders* โ one per lane, each in its own git worktree. The loop runs inside
|
|
11
|
+
task-scoped **spaces**: directories that hold repos, notes, and artifacts under
|
|
12
|
+
one obvious filesystem root. Nothing lives only in a chat window โ every
|
|
13
|
+
decision, spec, and verdict is committed to the space repo.
|
|
11
14
|
|
|
12
|
-
|
|
15
|
+
It installs **one executable**, `architect`. The spaces substrate and the
|
|
16
|
+
evergreen-checkout engine are two sibling gems:
|
|
13
17
|
|
|
14
|
-
|
|
|
15
|
-
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| **`src`** ๐ฒ | Tend evergreen repo checkouts for copy-on-write provisioning | `Space::Src` |
|
|
19
|
-
|
|
20
|
-
Each is a first-class executable. `architect` also forwards `architect space โฆ`
|
|
21
|
-
and `architect src โฆ` to the other two, so a project can drive everything from
|
|
22
|
-
one command when that's handier. ๐
|
|
23
|
-
|
|
24
|
-
## What's a space? ๐ช
|
|
25
|
-
|
|
26
|
-
A space is just a regular directory with a tiny YAML identity file and room for
|
|
27
|
-
everything a task needs:
|
|
28
|
-
|
|
29
|
-
```text
|
|
30
|
-
~/architect/spaces/20260531-name-of-space/
|
|
31
|
-
space.yaml # identity: id, title, status, repos, notes, tags
|
|
32
|
-
README.md
|
|
33
|
-
repos/ # cloned (or copy-on-write'd) repositories
|
|
34
|
-
notes/ # scratch, prompts, logs
|
|
35
|
-
architecture/ # iteration files: I<NN>-<name>.md + ARCHITECT.md index + BRIEF.md
|
|
36
|
-
build/ # lane worktrees + scratch (build/<id>-<lane>/)
|
|
37
|
-
tmp/ # workspace-local temp โ use this instead of /tmp
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Run a command from anywhere inside a space and it just works โ `space` and
|
|
41
|
-
`architect` walk up from `$PWD` until they find the nearest `space.yaml`. No
|
|
42
|
-
"current space" state to get out of sync; where you *are* is the space you
|
|
43
|
-
mean. ๐งญ
|
|
18
|
+
| Gem | Dependency | What it provides |
|
|
19
|
+
|-----|------------|------------------|
|
|
20
|
+
| **space-cadet** | hard | The spaces substrate (`Space::Core`): create, manage & containerize task-scoped workspaces โ the `space` binary โ plus the copy-on-write evergreen-checkout substrate repos provision from |
|
|
21
|
+
| **repo-tender** | soft | Evergreen clone tending โ the `repo-tender` binary (with the deprecated `src` shim) โ and the launchd agent the `architect sessions agent` commands drive. Install with `gem install repo-tender` when you want the session-sync rail โ everything else works without it |
|
|
44
22
|
|
|
45
23
|
## Installation ๐ฆ
|
|
46
24
|
|
|
47
|
-
Add it to your `Gemfile`:
|
|
48
|
-
|
|
49
|
-
```ruby
|
|
50
|
-
gem "space-architect"
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
bundle install
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Or grab it yourself:
|
|
58
|
-
|
|
59
25
|
```bash
|
|
60
26
|
gem install space-architect
|
|
27
|
+
gem install repo-tender # optional: enables the sessions launchd agent
|
|
61
28
|
```
|
|
62
29
|
|
|
63
|
-
The gem
|
|
64
|
-
`architect
|
|
65
|
-
|
|
66
|
-
## Quick start ๐
|
|
67
|
-
|
|
68
|
-
```sh
|
|
69
|
-
# Spaces
|
|
70
|
-
space init # create XDG config + state files
|
|
71
|
-
space new "Name of Space" # blast off a new space ๐
|
|
72
|
-
space new "Name of Space" -r org/repo -r org/lib # โฆwith repos cloned in (repeat -r)
|
|
73
|
-
space list # see all your spaces
|
|
74
|
-
space show # show the space you're standing in
|
|
75
|
-
|
|
76
|
-
# Evergreen checkouts (copy-on-write sources for fast provisioning)
|
|
77
|
-
src repo add github.com/example-org/example-app # tend it ๐ฒ
|
|
78
|
-
src sync # one sync pass
|
|
79
|
-
src status # per-repo evergreen status
|
|
80
|
-
|
|
81
|
-
# Architect Loop (run from inside a space)
|
|
82
|
-
architect install-skills # install agent skills (once per machine)
|
|
83
|
-
architect init # scaffold ARCHITECT.md + architecture/
|
|
84
|
-
architect new my-feature # scaffold the next iteration file
|
|
85
|
-
architect freeze my-feature # lock the Acceptance Criteria โ๏ธ
|
|
86
|
-
architect dispatch my-feature lane-a # send a headless builder to work
|
|
87
|
-
|
|
88
|
-
# Containers (run from inside a space) โ a portable, reproducible-by-SHA image of the space
|
|
89
|
-
space pack # render build/oci/ (Dockerfile + entrypoint)
|
|
90
|
-
space build # pack + build & tag <space-id>:<git-sha>
|
|
91
|
-
space run # run it โ login shell, auth from your env
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## `space` โ task-scoped workspaces ๐
|
|
95
|
-
|
|
96
|
-
```sh
|
|
97
|
-
space init
|
|
98
|
-
space new "Name of Space"
|
|
99
|
-
space new "Name of Space" -r org/repo -r example-tools/alpha -r example-tools/beta
|
|
100
|
-
space list # alias: space ls
|
|
101
|
-
space show 20260531-name-of-space
|
|
102
|
-
space path 20260531-name-of-space
|
|
103
|
-
space current # based on $PWD
|
|
104
|
-
space show # based on $PWD
|
|
105
|
-
space status # report: metadata + loop status (based on $PWD)
|
|
106
|
-
space status 20260531-name-of-space # report another space
|
|
107
|
-
space status done # set: active | paused | done | archived
|
|
108
|
-
space status 20260531-name-of-space done
|
|
109
|
-
space config set default_provider github.com
|
|
110
|
-
space config set default_organization example-org
|
|
111
|
-
space repo add example-app # github.com/example-org/example-app
|
|
112
|
-
space repo add example-tools/alpha example-tools/beta
|
|
113
|
-
space repo add gitlab.com/example-org/api
|
|
114
|
-
space repo resolve example-app example-tools/async
|
|
115
|
-
space repo ls # alias: space repos ls
|
|
116
|
-
space use 20260531-name-of-space # records recent state, prints the path
|
|
117
|
-
space ls --color=always # auto | always | never (--colors also accepted)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
`space status` is **report-or-set**: with no status keyword (bare, or with just
|
|
121
|
-
a space id) it *reports* the space โ its metadata plus a compact loop-status
|
|
122
|
-
block (project status, current iteration, derived state) when the space runs an
|
|
123
|
-
Architect project, quietly omitted otherwise; pass a status keyword (`active`,
|
|
124
|
-
`paused`, `done`, `archived`) to *set* it instead. ๐
|
|
125
|
-
|
|
126
|
-
Repos are passed with a repeatable `-r` flag (`-r org/repo -r org/lib`); the
|
|
127
|
-
comma form (`-r a,b`) works too. Space ids are date-prefixed
|
|
128
|
-
(`20260531-name-of-space`) so they sort naturally, and duplicate names on the
|
|
129
|
-
same day get a counter (`โฆ-name-of-space-2`). ๐
|
|
130
|
-
|
|
131
|
-
Everything `space` does is also reachable as `architect space โฆ` from within a
|
|
132
|
-
project.
|
|
133
|
-
|
|
134
|
-
## Containerize a space: `pack` ยท `build` ยท `run` ๐ฆ
|
|
135
|
-
|
|
136
|
-
A space is self-describing enough to become a container. `space pack` renders a
|
|
137
|
-
portable OCI build context from the space; `space build` packs and builds it into
|
|
138
|
-
a **reproducible-by-SHA** image; `space run` runs that image with your auth
|
|
139
|
-
injected at runtime and stateful paths bind-mounted back to the host. ๐ณ
|
|
140
|
-
|
|
141
|
-
```sh
|
|
142
|
-
space pack # render build/oci/ (Dockerfile + entrypoint + ignore file)
|
|
143
|
-
space pack -o /tmp/ctx # โฆto a different output directory
|
|
144
|
-
space build # pack, then build & tag <space-id>:<git-sha> and :latest
|
|
145
|
-
space run # run <space-id>:latest โ login shell, auth from your env
|
|
146
|
-
space run architect status # โฆor run a one-off command instead of the login shell
|
|
147
|
-
space run --tty # force an interactive TTY (default: auto-detect)
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**What lands in the image.** The context copies the whole space tree (filtered by
|
|
151
|
-
a generated `Dockerfile.dockerignore`) onto a `ruby:4.0.5` base with `git`, the
|
|
152
|
-
Claude Code CLI, and the `space-architect` gem โ installed from the in-space
|
|
153
|
-
`repos/space-architect` checkout when present (a pinned build), else from
|
|
154
|
-
RubyGems. Secrets never enter the layers: `.env`, `*.key`, `*.pem`, ssh keys,
|
|
155
|
-
`build/`, and `tmp/` are all excluded by the generated ignore file. ๐
|
|
156
|
-
|
|
157
|
-
**Reproducible by SHA.** `space build` tags the image `<space-id>:<sha>`, where
|
|
158
|
-
`<sha>` is the space repo's 12-char `HEAD` (suffixed `-dirty` when the tree has
|
|
159
|
-
uncommitted changes), plus a moving `:latest`. Same commit โ same tag โ same
|
|
160
|
-
image. It drives the `container` CLI, but the output is an ordinary OCI/Docker
|
|
161
|
-
build context, so `docker build -f build/oci/Dockerfile .` (from the space root)
|
|
162
|
-
works just as well.
|
|
163
|
-
|
|
164
|
-
**Auth stays out of the layers.** `space run` injects only the auth environment
|
|
165
|
-
variables that are actually set โ `ANTHROPIC_API_KEY`, `CLAUDE_CODE_OAUTH_TOKEN`,
|
|
166
|
-
`ANTHROPIC_BASE_URL` โ with `-e` at run time, so credentials live in your shell,
|
|
167
|
-
never in the image. ๐๏ธ
|
|
168
|
-
|
|
169
|
-
**Forwarding payload credentials.** Beyond the always-on auth trio, a space can declare
|
|
170
|
-
`run.env:` in `space.yaml` โ a list of host env var names forwarded into the container at
|
|
171
|
-
run time. You can also pass `space run --env VAR` (repeatable) for ad hoc additions. All
|
|
172
|
-
forwarding is bare `-e VAR` passthrough: values never appear in argv, `ps`, or the image.
|
|
173
|
-
A requested-but-unset var warns on stderr instead of silently failing inside the guest.
|
|
174
|
-
|
|
175
|
-
```yaml
|
|
176
|
-
run:
|
|
177
|
-
env: # run-time: host var names, forwarded as bare -e VAR
|
|
178
|
-
- FIREWORKS_API_KEY
|
|
179
|
-
- OPENAI_API_KEY
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**Declaring provisioning & persistence** โ two optional keys in `space.yaml`:
|
|
183
|
-
|
|
184
|
-
```yaml
|
|
185
|
-
pack:
|
|
186
|
-
provision: # build-time: relative scripts, baked in by `space build`
|
|
187
|
-
- scripts/setup-toolchain.sh
|
|
188
|
-
persist: # run-time: absolute guest paths, bind-mounted per run
|
|
189
|
-
- /root/.claude
|
|
190
|
-
- /root/.local/state
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
`provision` scripts must live under the space root and be executable. Each script is
|
|
194
|
-
copied into the image individually (`COPY <script> /space/<script>`) and then invoked
|
|
195
|
-
(`RUN /space/<script>`) **before** the full space tree lands and **before** the gem is
|
|
196
|
-
installed. This ordering is the cache-hygiene guarantee: editing any other space file
|
|
197
|
-
leaves the provision and gem-install layers cached, so a rebuild completes in seconds
|
|
198
|
-
instead of minutes. Scripts must therefore be self-contained โ they run with only the
|
|
199
|
-
base system layers and any earlier provision scripts' outputs; they cannot read other
|
|
200
|
-
space files or call `architect`/`space`. Scripts must have the executable bit set; COPY
|
|
201
|
-
preserves the mode from the build context.
|
|
202
|
-
|
|
203
|
-
`persist` paths must be absolute; `space run` bind-mounts each one from
|
|
204
|
-
`<space>/.state<path>` on the host (created on first run) so a container's mutable state
|
|
205
|
-
survives across runs. Both are validated at pack time.
|
|
206
|
-
|
|
207
|
-
Like everything else, these are reachable as `architect space pack|build|run`
|
|
208
|
-
from inside a project.
|
|
209
|
-
|
|
210
|
-
## `src` โ the evergreen engine ๐ฒ
|
|
211
|
-
|
|
212
|
-
`src` keeps local clones under `<src_dir>/<host>/<owner>/<repo>` (default
|
|
213
|
-
`~/architect/src/โฆ`) clean, on their default branch, and freshly fetched โ so
|
|
214
|
-
spaces can provision repos by **copy-on-write** instead of cloning over the
|
|
215
|
-
network.
|
|
216
|
-
|
|
217
|
-
```sh
|
|
218
|
-
src repo add github.com/example-org/example-app # track + tend a repo
|
|
219
|
-
src org add github.com/example-org # track a whole org
|
|
220
|
-
src sync # run one sync pass (--repo to scope)
|
|
221
|
-
src status # per-repo evergreen status table
|
|
222
|
-
src clone example-app # APFS copy-on-write into $PWD
|
|
223
|
-
src daemon install # per-user launchd agent for background sync
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
When `space repo add` finds a matching evergreen checkout, it copy-on-writes
|
|
227
|
-
from it instead of hitting the network โ instant provisioning. โก The two
|
|
228
|
-
surfaces share one layout by design, so they line up with zero configuration:
|
|
229
|
-
|
|
230
|
-
```sh
|
|
231
|
-
src repo add github.com/example-org/example-app # tend it: keep it evergreen ๐ฒ
|
|
232
|
-
space repo add example-app # copies it instantly โก
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
`src` has its own `--plain` / `--json` output modes for scripting, and its own
|
|
236
|
-
fish integration (`src shell fish install`).
|
|
237
|
-
|
|
238
|
-
## `architect` โ the Architect Loop ๐๏ธ
|
|
239
|
-
|
|
240
|
-
The **Architect Loop** is a structured build cycle for you and headless AI
|
|
241
|
-
builders. Each loop lives inside a space as a *project*.
|
|
242
|
-
|
|
243
|
-
**Roles:**
|
|
244
|
-
|
|
245
|
-
- **Architect** โ the judgment role: a strong reasoning model (or you), run
|
|
246
|
-
interactively. Arbitrates disagreements, writes and freezes iteration files,
|
|
247
|
-
calls kill/continue, merges builder output. Never writes implementation code.
|
|
248
|
-
- **Builder** โ the execution role: a cheaper model run headless via `architect
|
|
249
|
-
dispatch`, one per lane in its own git worktree. Reads the iteration's Builder
|
|
250
|
-
Prompt, does the work, writes raw evidence to `build/<id>-<lane>/report.md`.
|
|
251
|
-
Never grades its own work; never edits `architecture/`.
|
|
252
|
-
|
|
253
|
-
The loop is **model-agnostic** โ which models fill the two roles is your choice
|
|
254
|
-
(e.g. a strong Claude model judging a cheaper one on the same plan, or a
|
|
255
|
-
cross-vendor pairing for more independent review). Set it per dispatch with
|
|
256
|
-
`architect dispatch --model โฆ`, or run several pairings head-to-head as a
|
|
257
|
-
**variant set** (`architect variant add`). See
|
|
258
|
-
[docs/DESIGN.md](docs/DESIGN.md) ยง1โยง2 for the reasoning.
|
|
259
|
-
|
|
260
|
-
**Filesystem layout:**
|
|
261
|
-
|
|
262
|
-
```text
|
|
263
|
-
architecture/
|
|
264
|
-
ARCHITECT.md # cross-iteration index; project-wide state
|
|
265
|
-
BRIEF.md # durable ยง-numbered project contract (optional)
|
|
266
|
-
I01-<iteration>.md # one self-contained file per iteration
|
|
267
|
-
build/
|
|
268
|
-
I01-<iteration>-<lane>/ # lane worktree + scratch per dispatch
|
|
269
|
-
run.jsonl # streamed builder output
|
|
270
|
-
report.md # builder report (transcribed into the iteration file verbatim)
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
**Iteration file anatomy** โ one file, grown section by section. You author the
|
|
274
|
-
*content* in fresh scratch files; the CLI owns the *persistence* (each command
|
|
275
|
-
writes the section, commits it, and prints back what changed). Every committing
|
|
276
|
-
command takes `-m`/`--message` and `--message-from <file>` โ your first line
|
|
277
|
-
completes the subject after a short canonical prefix (`I01 spec: <subject>`),
|
|
278
|
-
the rest becomes the body. The space's git log is the loop's durable memory:
|
|
279
|
-
write detailed messages.
|
|
280
|
-
|
|
281
|
-
| Section | Holds | How you persist it |
|
|
282
|
-
|---------|-------|--------------------|
|
|
283
|
-
| `## Grounds` | why โ research / brief distilled (optional) | `architect section <it> grounds --from <f>` |
|
|
284
|
-
| `## Specification` | what/how โ the full delegation contract | `architect section <it> specification --from <f>` |
|
|
285
|
-
| `## Acceptance Criteria` | proof โ exact gate commands + thresholds | `architect freeze <it>` โ๏ธ |
|
|
286
|
-
| `## Builder Prompt` | the exact lane-prompt(s) dispatched | `architect section <it> prompt --append --lane <l> --from <f>` |
|
|
287
|
-
| `## Builder Report` | raw evidence, transcribed verbatim | `architect evidence <it> --lane <l>` |
|
|
288
|
-
| `## Verdict` | rulings + per-AC PASS/FAIL + KILL/CONTINUE | `architect section <it> verdict --from <f>` |
|
|
30
|
+
The gem installs one executable: `architect`. ๐ (Or add
|
|
31
|
+
`gem "space-architect"` to your Gemfile and `bundle install`.)
|
|
289
32
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
afterward is an automatic iteration FAIL. The builder never edits the iteration
|
|
294
|
-
file.
|
|
33
|
+
Upgrading from the 8.x monolith? Uninstall `space-architect` 8.x **first** โ
|
|
34
|
+
its `space`/`src` executables collide with the ones the new gems ship โ see
|
|
35
|
+
[the upgrade guide](docs/how-to/upgrade-from-the-8x-monolith.md).
|
|
295
36
|
|
|
296
|
-
|
|
297
|
-
runs `architect ground` (emitting `ARCHITECT.md`, `BRIEF.md`, and the in-flight
|
|
298
|
-
iteration) so every fresh session starts oriented โ the loop leans on
|
|
299
|
-
fresh-session judgment, and this is what makes picking up cold cheap. Builders
|
|
300
|
-
inside a lane worktree are never grounded.
|
|
37
|
+
## 60-second start ๐
|
|
301
38
|
|
|
302
|
-
|
|
39
|
+
Run one full loop iteration in a scratch space โ the
|
|
40
|
+
[tutorial](docs/tutorials/one-loop-iteration.md) walks it end to end:
|
|
303
41
|
|
|
304
42
|
```sh
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
architect
|
|
308
|
-
architect
|
|
309
|
-
architect freeze <iteration> # freeze the Acceptance Criteria โ๏ธ
|
|
310
|
-
architect worktree add <repo> <it> <lane> # isolated worktree per lane (2โ4 lanes)
|
|
311
|
-
architect dispatch <it> <lane> --prompt <f> # copy the lane prompt in + dispatch a builder (--detach to survive long runs)
|
|
312
|
-
architect verify <iteration> # post-flight mechanical checks (reports only)
|
|
313
|
-
architect evidence <it> --lane <lane> # transcribe the builder's report verbatim
|
|
314
|
-
architect gate <iteration> # run the frozen gate commands, stream raw output
|
|
315
|
-
architect merge <it> <lane> # integrate ONE judged-passing lane (--no-ff)
|
|
316
|
-
architect integrate <it> --lanes a,b # integrate a set of passing lanes, in order
|
|
317
|
-
# landing (PR body + push/PR command) is the architect's end-of-project procedure (see skill)
|
|
318
|
-
architect status # project state (read-only)
|
|
319
|
-
architect variant add|compare|promote โฆ # competing (harness, model) lanes over one frozen spec
|
|
320
|
-
architect research dispatch|status|wait โฆ # parallel read-only research lanes (see below)
|
|
43
|
+
space init # create the XDG config + state files (space-cadet gem)
|
|
44
|
+
space new "Docsmith Tutorial" # blast off a new space ๐
|
|
45
|
+
cd ~/architect/spaces/<id>-docsmith-tutorial
|
|
46
|
+
architect init # scaffold ARCHITECT.md + the space.yaml project: block
|
|
321
47
|
```
|
|
322
48
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
(project status + current iteration) so you can see where you are in the loop. ๐งญ
|
|
49
|
+
From there the loop is: `architect new` โ `architect section โฆ` โ `architect
|
|
50
|
+
freeze` โ `architect dispatch` โ `architect gate` โ `architect integrate`. The
|
|
51
|
+
tutorial runs every step on a scratch repo.
|
|
327
52
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
```sh
|
|
331
|
-
architect init # first time
|
|
332
|
-
architect new my-feature # scaffold I01-my-feature.md
|
|
333
|
-
architect section my-feature specification --from spec.md -m "pull-based dispatcher seam"
|
|
334
|
-
architect freeze my-feature # lock it โ๏ธ
|
|
335
|
-
architect dispatch my-feature lane-a --prompt tmp/prompts/I01-lane-a.md --detach # send a builder; poll the report
|
|
336
|
-
architect verify my-feature # mechanical post-flight checks
|
|
337
|
-
architect evidence my-feature --lane lane-a # transcribe raw evidence
|
|
338
|
-
architect gate my-feature # run the frozen gates yourself
|
|
339
|
-
# โฆ read the diff against the spec, then write the Verdict โฆ
|
|
340
|
-
architect integrate my-feature --lanes lane-a # merge passing lanes โ project/<slug>
|
|
341
|
-
# landing (PR body + push/PR command) is the architect's end-of-project procedure (see skill)
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
### Streaming builder output ๐ก
|
|
345
|
-
|
|
346
|
-
`architect dispatch` can push the builder's pi JSONL event stream to an ingest
|
|
347
|
-
server for
|
|
348
|
-
live viewing:
|
|
349
|
-
|
|
350
|
-
```sh
|
|
351
|
-
# Push to an already-created run (you supply the full ingest URL):
|
|
352
|
-
architect dispatch my-feature lane-a \
|
|
353
|
-
--push-url $HOST/runs/<id>/ingest \
|
|
354
|
-
--push-token $INGEST_TOKEN
|
|
355
|
-
|
|
356
|
-
# Create a run and push in one step (requires --push-token = server's INGEST_TOKEN):
|
|
357
|
-
architect dispatch my-feature lane-a \
|
|
358
|
-
--push-host $HOST \
|
|
359
|
-
--push-token $INGEST_TOKEN
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
`--push-host` POSTs to `<HOST>/runs`, parses the new run id from the `201`
|
|
363
|
-
response, derives `<HOST>/runs/<id>/ingest`, and streams there; the created run
|
|
364
|
-
id and ingest URL are printed after dispatch starts. `--push-url` and
|
|
365
|
-
`--push-host` are mutually exclusive, both require `--push-token`, and neither
|
|
366
|
-
can be combined with `--detach` (the push tees the live pipe in-process).
|
|
367
|
-
|
|
368
|
-
### Research lanes ๐ญ
|
|
369
|
-
|
|
370
|
-
When an iteration needs facts the repo doesn't already have, fan out parallel
|
|
371
|
-
**read-only** research lanes โ detached `pi -p --mode json` researchers
|
|
372
|
-
(read-only by prompt contract; the supervisor-injected guard denies git writes)
|
|
373
|
-
that you supervise:
|
|
374
|
-
|
|
375
|
-
```sh
|
|
376
|
-
architect research dispatch 01-official-api.prompt.md 02-changelog.prompt.md
|
|
377
|
-
architect research wait # tails each lane's run.jsonl; --level 1-4, --quiet, --thinking
|
|
378
|
-
architect research status # status of dispatched runs
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
Researchers gather; the architect verifies the load-bearing claims against
|
|
382
|
-
sources and writes the iteration's **Grounds** section.
|
|
383
|
-
|
|
384
|
-
### Skills ๐ง
|
|
385
|
-
|
|
386
|
-
`architect install-skills` installs the bundled `architect`,
|
|
387
|
-
`architect-research`, and `architect-vocabulary` skills for your harness:
|
|
388
|
-
|
|
389
|
-
```sh
|
|
390
|
-
architect install-skills # default: claude (~/.claude/skills/)
|
|
391
|
-
architect install-skills --provider opencode # or codex | pi
|
|
392
|
-
architect install-skills --project # into ./โฆ instead of globally
|
|
393
|
-
architect install-skills --dry-run # show what would change
|
|
394
|
-
```
|
|
53
|
+
## The four quadrants ๐งญ
|
|
395
54
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
and `src` each ship a small fish wrapper function plus completions (commands,
|
|
403
|
-
subcommands, spaces, statuses, config keys, repo refs). Install into fish's
|
|
404
|
-
autoloaded directories:
|
|
405
|
-
|
|
406
|
-
```fish
|
|
407
|
-
space shell fish install
|
|
408
|
-
src shell fish install
|
|
409
|
-
exec fish
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
After restarting fish (or `exec fish`), `space new "โฆ"` and
|
|
413
|
-
`space use <id>` will `cd` into the selected space once the command succeeds;
|
|
414
|
-
every other command keeps normal CLI behavior. ๐ช The functions and completions
|
|
415
|
-
are written under `~/.config/fish/`, so there's no need to edit `config.fish`.
|
|
416
|
-
For one-off testing without installing:
|
|
417
|
-
|
|
418
|
-
```fish
|
|
419
|
-
space shell init fish | source
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
## Configuration โ๏ธ
|
|
423
|
-
|
|
424
|
-
Config lives at `~/.config/space-architect/config.yml` (XDG-aware) and defaults to:
|
|
425
|
-
|
|
426
|
-
```yaml
|
|
427
|
-
version: 1
|
|
428
|
-
base_dir: ~/architect # spaces_dir + src_dir hang off this by default
|
|
429
|
-
default_provider: github.com
|
|
430
|
-
default_organization:
|
|
431
|
-
git_clone_protocol: ssh # ssh | https
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
Derived defaults: `spaces_dir` โ `<base_dir>/spaces`, `src_dir` (evergreen
|
|
435
|
-
checkout root) โ `<base_dir>/src`. Override either explicitly. View values with
|
|
436
|
-
`space config show`; set one with `space config set KEY VALUE`. Editable keys:
|
|
437
|
-
`base_dir`, `spaces_dir`, `src_dir`, `default_provider`, `default_organization`,
|
|
438
|
-
`git_clone_protocol`.
|
|
439
|
-
|
|
440
|
-
## Repos: evergreen, copy-on-write, concurrent โก
|
|
441
|
-
|
|
442
|
-
Repos are added to the current space under `repos/` and tracked in `space.yaml`.
|
|
443
|
-
When an up-to-date evergreen checkout exists at
|
|
444
|
-
`<src_dir>/<host>/<owner>/<name>` (e.g.
|
|
445
|
-
`~/architect/src/github.com/example-org/example-app`), `space` copies it into the
|
|
446
|
-
space instead of cloning over the network โ a copy-on-write clone on APFS. โก
|
|
447
|
-
Set `src_dir` empty to always clone:
|
|
448
|
-
|
|
449
|
-
```sh
|
|
450
|
-
space config set src_dir ""
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
Clone URLs default to SSH (`git@github.com:example-org/example-app.git`); switch
|
|
454
|
-
with `space config set git_clone_protocol https`. Multiple repos passed to
|
|
455
|
-
`space repo add` are fetched **concurrently**, up to five at a time, on fibers โ
|
|
456
|
-
no threads, all cooperative. ๐งต After each repo lands, `space` runs `mise trust`
|
|
457
|
-
in it. Each space also gets a workspace-local `tmp/` โ use it instead of `/tmp`.
|
|
458
|
-
|
|
459
|
-
## Embedding ๐
|
|
460
|
-
|
|
461
|
-
The library is split into three namespaces you can require independently:
|
|
462
|
-
|
|
463
|
-
- **`Space::Core`** โ the foundation: config, state, XDG, terminal, git/mise
|
|
464
|
-
clients, the space store. The `space` CLI runs on this alone.
|
|
465
|
-
- **`Space::Architect`** โ project state, the builder harness, dispatch, and the
|
|
466
|
-
research supervisor.
|
|
467
|
-
- **`Space::Src`** โ the evergreen engine (tracking, sync, copy-on-write clone).
|
|
468
|
-
|
|
469
|
-
```ruby
|
|
470
|
-
require "space_core" # just spaces
|
|
471
|
-
require "space_architect" # the full loop (pulls in core + src)
|
|
472
|
-
require "space_src" # just the evergreen engine
|
|
473
|
-
```
|
|
474
|
-
|
|
475
|
-
## Documentation ๐
|
|
476
|
-
|
|
477
|
-
- **[Command Reference](docs/reference.md)** โ every command, flag, and behavior
|
|
478
|
-
- **[Design](docs/DESIGN.md)** โ the source-backed rationale: the twelve invariant rules (R1โR12), the failure-mode โ mitigation table, and why the loop is shaped this way
|
|
479
|
-
- **[Changelog](CHANGELOG.md)** โ release history
|
|
55
|
+
| Quadrant | Read it when youโฆ | Start here |
|
|
56
|
+
|----------|-------------------|------------|
|
|
57
|
+
| **Tutorials** โ learning-oriented | are new and want a guided journey | [docs/tutorials](docs/tutorials/) |
|
|
58
|
+
| **How-to guides** โ goal-oriented | have a specific task to do | [docs/how-to](docs/how-to/) |
|
|
59
|
+
| **Reference** โ information-oriented | need a fact about a command, flag, or file | [docs/reference](docs/reference/) |
|
|
60
|
+
| **Explanation** โ understanding-oriented | want the why behind the design | [docs/explanation](docs/explanation/) |
|
|
480
61
|
|
|
481
62
|
## Development ๐ ๏ธ
|
|
482
63
|
|
|
@@ -487,15 +68,9 @@ bundle exec rake build # build the gem into pkg/
|
|
|
487
68
|
bundle exec rake install # build + install into your user gem home
|
|
488
69
|
```
|
|
489
70
|
|
|
490
|
-
## Contributing ๐
|
|
491
|
-
|
|
492
71
|
Bug reports and pull requests are welcome on GitHub at
|
|
493
|
-
[https://github.com/jetpks/space-architect](https://github.com/jetpks/space-architect)
|
|
494
|
-
|
|
495
|
-
## License ๐
|
|
496
|
-
|
|
497
|
-
Available as open source under the terms of the
|
|
498
|
-
[MIT License](https://opensource.org/licenses/MIT).
|
|
72
|
+
[https://github.com/jetpks/space-architect](https://github.com/jetpks/space-architect).
|
|
73
|
+
Available as open source under the [MIT License](LICENSE.txt).
|
|
499
74
|
|
|
500
75
|
---
|
|
501
76
|
|