space-architect 9.3.0 → 9.4.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: 4fd0baee9b2db69fa1ef96c1b4993f75a8912b5b0898d012c13036a379e32a7f
4
- data.tar.gz: 582172fa5c61e4a9419409cafdfa8701ca096a2621527141099944f3261c6592
3
+ metadata.gz: e768903f0762630e4c4c510a83621cf4c82be30ea7d95026d794f90d70205f44
4
+ data.tar.gz: 77c7b1faae07696200558929456ab481aa5f8f061f69a0ff923fac53a4957f2c
5
5
  SHA512:
6
- metadata.gz: 59dd000d01b8fd0b42729d87f7f843f93690b0fbccf927e127426f352fa79aada6078a885b54e3342d3c901500fde93338be3198b77e871df85f7b28ef816f9e
7
- data.tar.gz: 29f88c1fdec961ed7b53d9d9e4a3a3c156cadac2da157786bea28fca4b20b09cb786ab195d5eedf0877e11c901a2d140d66347bbee3fc52570a4a68225b78284
6
+ metadata.gz: 27e9c5abd1ae5a60b42aee5bed88640b3dd49352214b2af420384333b8d93c558369e14220f4f996729d1ccdcf4155552e05dbd59c0ffaf05ca81fe0ea4f9489
7
+ data.tar.gz: 5e86aa794e2ec154f8e797040cdadd6a59c43489bf98ffdb070f8e7d90a82572e73f19ba5cadedfebdd90fea29062fd0fa873e9bba08cf06f1277483a60e7ee0
data/CHANGELOG.md CHANGED
@@ -5,6 +5,39 @@ 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.4.0] - 2026-10-17
9
+
10
+ ### Added
11
+
12
+ - **The skill family.** `/architect` is now the inline working mode — work
13
+ outside the loop at a conversational cadence (UI, ops, small fixes), with
14
+ the space as the workspace (notes kept, `ARCHITECT.md` updated, commits
15
+ when the work calls for them) and the vocabulary glossary folded in.
16
+ **`/architect-discuss`** carries the judgment seat: exploration,
17
+ arbitration, judging finished runs, landing, iteration surgery.
18
+ **`/architect-status`** reports state read-only from CLI output and the
19
+ newest notes. The coordinator launch is agent-owned end to end:
20
+ **`/architect-action`** (renamed from `/architect-plan`) launches via the
21
+ new `architect_loop` pi-extension tool (jetpks/pi-extensions) — the
22
+ agent-side equivalent of `/loop`, sharing one spawn path so the two cannot
23
+ drift, awaiting the run id, then self-compacting the launching session
24
+ into a small on-call escalation seat.
25
+
26
+ ### Changed
27
+
28
+ - The `install-skills` help text, `docs/DESIGN.md`, and
29
+ `docs/reference/project.md` describe the five-skill family; the
30
+ `/architect-discuss` routing section now describes the real dual
31
+ agent-file mechanism (per-space `.pi/agents/` generation with resolved
32
+ pins, plus user-level `install-agents` playbooks as the headless/
33
+ untrusted fallback) instead of claiming nothing generates into the space.
34
+
35
+ ### Removed
36
+
37
+ - **`/architect-plan`** (renamed to `/architect-action`) and
38
+ **`/architect-vocabulary`** (folded into `/architect`); the `dispatch.md`
39
+ and `research.md` companion references moved to the discuss skill.
40
+
8
41
  ## [9.3.0] - 2026-10-17
9
42
 
10
43
  ### Removed
@@ -1713,7 +1713,7 @@ module Space::Architect
1713
1713
  # two paths looked at, and the default in use.
1714
1714
  def default_model_inform
1715
1715
  "model: no architect.yaml found (looked at #{Routing.space_path(space.path)} + #{Routing.global_path}) — " \
1716
- "using default '#{Harness::DEFAULT_MODEL}'"
1716
+ "using default '#{Harness::DEFAULT_MODEL}' #{Routing::INIT_HINT}"
1717
1717
  end
1718
1718
 
1719
1719
  # --prompt: the caller authors the lane prompt anywhere (a fresh scratch file) and
@@ -169,7 +169,9 @@ module Space::Architect
169
169
  # Legacy lanes store no model — resolve the config layer once so the
170
170
  # display shows what they would actually route, and mark the bare
171
171
  # constant as the last resort it is, not ordinary behavior.
172
- config_model = Routing.for_space(sp.path)&.dig("builder", "model")
172
+ # Fully qualified: the Architect::Routing subcommand namespace
173
+ # (I09) lexically shadows Space::Architect::Routing inside this module.
174
+ config_model = Space::Architect::Routing.for_space(sp.path)&.dig("builder", "model")
173
175
 
174
176
  terminal.say "Project status: #{block['status'] || '(none)'}"
175
177
  terminal.say "Current iteration: #{block['current_iteration'] || '(none)'}"
@@ -1060,7 +1062,7 @@ module Space::Architect
1060
1062
  end
1061
1063
 
1062
1064
  class InstallSkills < BaseCommand
1063
- desc "Install bundled skills (architect, architect-research, architect-vocabulary) for a harness"
1065
+ desc "Install bundled skills (architect, architect-discuss, architect-action, architect-status, architect-research) for a harness"
1064
1066
  phase 53, "Project"
1065
1067
  option :provider, default: "claude", desc: "Skill install target (default: claude; validated by the installer)"
1066
1068
  option :project, type: :boolean, default: false, desc: "Install to CWD instead of global"
@@ -1100,6 +1102,56 @@ module Space::Architect
1100
1102
  end
1101
1103
  end
1102
1104
 
1105
+ module Routing
1106
+ # I09: `architect routing init` — the self-service cure for the
1107
+ # missing-config wall (default_model_inform's hint names this command).
1108
+ # Writes Routing::TEMPLATE verbatim and round-trips the write through
1109
+ # Routing.parse before claiming success; the routing machinery itself
1110
+ # is untouched — the command only writes a file it already accepts.
1111
+ class Init < BaseCommand
1112
+ desc "Write a commented starter architect.yaml (space root by default; --global for the machine-wide config)"
1113
+ phase 53, "Project"
1114
+ argument :space, required: false, desc: "Space identifier (default: $PWD)"
1115
+ option :global, type: :boolean, default: false,
1116
+ desc: "Write ~/.config/space-architect/architect.yaml (the machine-wide config; SPACE_ARCHITECT_GLOBAL_CONFIG overrides the path) instead of the space root, creating parent directories as needed"
1117
+
1118
+ def call(space: nil, global: false, **opts)
1119
+ setup_terminal(**opts.slice(:color, :colors))
1120
+ handle_errors do
1121
+ target =
1122
+ if global
1123
+ raise Space::Core::Error, "--global and an explicit space argument are mutually exclusive" if space
1124
+ # Routing.global_path is the env-overridable canonical path — never re-derive it here.
1125
+ path = Space::Architect::Routing.global_path
1126
+ FileUtils.mkdir_p(path.dirname)
1127
+ path
1128
+ else
1129
+ # The house walk-up: empty identifier looks for space.yaml from $PWD upward.
1130
+ found = store.find(space).value_or(nil)
1131
+ unless found
1132
+ raise Space::Core::Error,
1133
+ "no space.yaml found upward from #{Dir.pwd} — run `architect routing init --global` to scaffold the machine-wide config instead"
1134
+ end
1135
+ Space::Architect::Routing.space_path(found.path)
1136
+ end
1137
+
1138
+ raise Space::Core::Error, "architect.yaml already exists: #{target} — routing init never overwrites" if target.exist?
1139
+
1140
+ File.write(target, Space::Architect::Routing::TEMPLATE)
1141
+ # A scaffold that fails its own parser (or misses a required role)
1142
+ # is a bug — validate the round-trip, let the error escape loud.
1143
+ parsed = Space::Architect::Routing.parse(File.read(target), target)
1144
+ missing = Space::Architect::Routing::REQUIRED_ROLES - parsed.keys
1145
+ raise Space::Core::Error, "scaffolded #{target} is missing required roles: #{missing.join(', ')}" if missing.any?
1146
+
1147
+ terminal.say "Wrote starter routing config: #{terminal.path(target.to_s)}"
1148
+ terminal.say "Edit the example/REPLACE_ME models; the next command or /loop picks the file up."
1149
+ CLI.record_outcome(Outcome.new(exit_code: 0))
1150
+ end
1151
+ end
1152
+ end
1153
+ end
1154
+
1103
1155
  module Worktree
1104
1156
  class Add < BaseCommand
1105
1157
  desc "Create a worktree for a lane"
@@ -1340,6 +1392,9 @@ Space::Architect::CLI::Registry.register "worktree" do |wt|
1340
1392
  wt.register "remove", Space::Architect::CLI::Architect::Worktree::Remove
1341
1393
  wt.register "list", Space::Architect::CLI::Architect::Worktree::List
1342
1394
  end
1395
+ Space::Architect::CLI::Registry.register "routing" do |r|
1396
+ r.register "init", Space::Architect::CLI::Architect::Routing::Init
1397
+ end
1343
1398
  Space::Architect::CLI::Registry.register "variant" do |v|
1344
1399
  v.register "add", Space::Architect::CLI::Architect::Variant::Add
1345
1400
  v.register "promote", Space::Architect::CLI::Architect::Variant::Promote
@@ -22,6 +22,49 @@ module Space::Architect
22
22
  REQUIRED_ROLES = %w[spec builder judge coordinator narrator].freeze
23
23
  ENTRY_KEYS = %w[model thinking].freeze
24
24
 
25
+ # I09: the `architect routing init` scaffold — the exact bytes the command
26
+ # writes, living beside the parsers that must accept it. Example models are
27
+ # loud REPLACE_MEs; the header comment carries both locations and the merge
28
+ # order so the file is self-documenting. Byte-exact contract: the extension
29
+ # lane's tests carry an inline copy, and the command round-trips the write
30
+ # through parse below — a template the machinery rejects is a bug.
31
+ TEMPLATE = <<~'YAML'.freeze
32
+ # architect.yaml — space-architect loop role routing, scaffolded by `architect routing init`.
33
+ # Locations (merged in this order; the space-local entry wins per role):
34
+ # global: ~/.config/space-architect/architect.yaml (machine-wide)
35
+ # local: architect.yaml beside this space's space.yaml (this file)
36
+ # A local entry overrides the global entry for THAT ROLE only; after the
37
+ # merge every agent role must be routed: spec, builder, judge, coordinator,
38
+ # narrator (architect is optional).
39
+ # Replace every example/REPLACE_ME below with a real provider/model-id
40
+ # (e.g. zai/glm-5.3). thinking is optional: off|minimal|low|medium|high|xhigh|max.
41
+ # Once saved, the next /loop or architect command picks the file up.
42
+ version: 1
43
+ roles:
44
+ architect:
45
+ model: example/REPLACE_ME
46
+ thinking: high
47
+ spec:
48
+ model: example/REPLACE_ME
49
+ thinking: high
50
+ builder:
51
+ model: example/REPLACE_ME
52
+ thinking: high
53
+ judge:
54
+ model: example/REPLACE_ME
55
+ thinking: high
56
+ coordinator:
57
+ model: example/REPLACE_ME
58
+ thinking: high
59
+ narrator:
60
+ model: example/REPLACE_ME
61
+ thinking: low
62
+ YAML
63
+
64
+ # The one canonical cure line appended to default_model_inform's last-resort
65
+ # inform — self-punctuating, appended after a single space by the caller.
66
+ INIT_HINT = "Create one: `architect routing init` (beside space.yaml) or `architect routing init --global` (~/.config/space-architect/architect.yaml).".freeze
67
+
25
68
  def self.global_path
26
69
  env = ENV["SPACE_ARCHITECT_GLOBAL_CONFIG"]
27
70
  return Pathname.new(env) unless env.nil?
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Space
4
4
  module Architect
5
- VERSION = "9.3.0"
5
+ VERSION = "9.4.0"
6
6
  end
7
7
  end