claude-company 0.2.0 → 0.2.4
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.
- package/.claude/hooks/guard_models.py +121 -5
- package/.claude/settings.json +3 -0
- package/ORCHESTRATOR.md +5 -0
- package/company/GATES.md +3 -1
- package/company/METHOD.md +10 -0
- package/company/models.json +7 -0
- package/company/state/DECISIONS.md +7 -1
- package/company/state/RESUME.md +99 -8
- package/company/state/STATUS.md +17 -3
- package/company/state/WORRIES.md +7 -0
- package/company/witnesses.json +127 -1
- package/docs/customizing.md +2 -0
- package/install.sh +83 -13
- package/package.json +4 -1
- package/update.sh +118 -8
- package/company/briefs/shipped/brief-adr-hardening.md +0 -100
- package/company/briefs/shipped/brief-cli-self-update.md +0 -168
- package/company/briefs/shipped/brief-cli-update.md +0 -219
- package/company/briefs/shipped/brief-delegation-enforcement.md +0 -484
- package/company/briefs/shipped/brief-docs-sync.md +0 -113
- package/company/briefs/shipped/brief-wave1-enforcement.md +0 -184
- package/company/briefs/shipped/brief-wave2-doctrine.md +0 -162
- package/company/briefs/shipped/brief-wave2-enforce.md +0 -200
- package/company/briefs/shipped/brief-wave3-sdlc.md +0 -180
- package/company/change-requests/CR-UPD-1-freeze-update-artifacts.md +0 -54
- package/company/specs/shipped/spec-cli-self-update.md +0 -409
- package/company/specs/shipped/spec-cli-update.md +0 -431
|
@@ -43,6 +43,26 @@ def load_manifest(root):
|
|
|
43
43
|
return roles
|
|
44
44
|
|
|
45
45
|
|
|
46
|
+
def load_builtins(root):
|
|
47
|
+
"""Return {type: model} from company/models.json `builtins`, or None.
|
|
48
|
+
|
|
49
|
+
Mirrors load_manifest and fails open (None) on a missing/malformed/
|
|
50
|
+
unreadable file or section. Keys starting with '$' (e.g. "$comment") are
|
|
51
|
+
dropped so they are never treated as a spawnable type, and only string
|
|
52
|
+
model values are kept.
|
|
53
|
+
"""
|
|
54
|
+
cfg = c.read_json_file(os.path.join(root, "company", "models.json"))
|
|
55
|
+
if not isinstance(cfg, dict):
|
|
56
|
+
return None
|
|
57
|
+
builtins = cfg.get("builtins")
|
|
58
|
+
if not isinstance(builtins, dict):
|
|
59
|
+
return None
|
|
60
|
+
return {
|
|
61
|
+
k: v for k, v in builtins.items()
|
|
62
|
+
if not k.startswith("$") and isinstance(v, str)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
46
66
|
def is_hotfix(root):
|
|
47
67
|
task = c.active_task(root)
|
|
48
68
|
return isinstance(task, dict) and task.get("type") == "hotfix"
|
|
@@ -67,15 +87,53 @@ def new_text(tool_name, tool_input):
|
|
|
67
87
|
return "\n".join(parts)
|
|
68
88
|
|
|
69
89
|
|
|
70
|
-
def handle_spawn(root, tool_input, roles):
|
|
90
|
+
def handle_spawn(root, tool_input, roles, builtins):
|
|
71
91
|
role = None
|
|
72
92
|
for field in SPAWN_TYPE_FIELDS:
|
|
73
93
|
val = tool_input.get(field)
|
|
74
94
|
if val:
|
|
75
95
|
role = val
|
|
76
96
|
break
|
|
77
|
-
if role is None
|
|
78
|
-
return #
|
|
97
|
+
if role is None:
|
|
98
|
+
return # no spawn type -> allow
|
|
99
|
+
if role in roles:
|
|
100
|
+
# OQ-MRA-02 assumption: roles governs on any collision - a type present
|
|
101
|
+
# in both `roles` and `builtins` is decided here, by the roles branch.
|
|
102
|
+
handle_role_spawn(root, tool_input, roles, role)
|
|
103
|
+
return
|
|
104
|
+
# Not a manifest role. A built-in agent type has no .claude/agents
|
|
105
|
+
# frontmatter to inherit from, so a bare spawn would silently take the
|
|
106
|
+
# SESSION model - require an explicit matching override.
|
|
107
|
+
if builtins is None:
|
|
108
|
+
return # no builtins section -> builtin enforcement inert (fail open)
|
|
109
|
+
if role not in builtins:
|
|
110
|
+
return # unknown type -> allow
|
|
111
|
+
pin = builtins[role]
|
|
112
|
+
override = tool_input.get("model")
|
|
113
|
+
if override == pin:
|
|
114
|
+
return # explicit matching override -> allow
|
|
115
|
+
if is_hotfix(root):
|
|
116
|
+
c.log_bypass(root, HOOK, "spawn " + role, "hotfix mode")
|
|
117
|
+
return
|
|
118
|
+
if not override:
|
|
119
|
+
c.block(
|
|
120
|
+
root, HOOK, "spawn " + role,
|
|
121
|
+
"builtin spawn no override (pin {})".format(pin),
|
|
122
|
+
"BLOCKED: spawning built-in '{}' with no model override would "
|
|
123
|
+
"inherit the session model - built-in agent types have no "
|
|
124
|
+
"company/models.json frontmatter pin to fall back on.\n"
|
|
125
|
+
"Fix: pass model: '{}'".format(role, pin),
|
|
126
|
+
)
|
|
127
|
+
c.block(
|
|
128
|
+
root, HOOK, "spawn " + role,
|
|
129
|
+
"builtin spawn override {} != pin {}".format(override, pin),
|
|
130
|
+
"BLOCKED: spawning built-in '{}' with model '{}' contradicts "
|
|
131
|
+
"company/models.json (built-in pin: '{}').\n"
|
|
132
|
+
"Fix: pass model: '{}'".format(role, override, pin, pin),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def handle_role_spawn(root, tool_input, roles, role):
|
|
79
137
|
override = tool_input.get("model")
|
|
80
138
|
if not override:
|
|
81
139
|
return # no override -> role inherits the manifest model, allow
|
|
@@ -124,8 +182,53 @@ def handle_frontmatter_edit(root, tool_name, tool_input, roles):
|
|
|
124
182
|
)
|
|
125
183
|
|
|
126
184
|
|
|
185
|
+
def check_spawn_wiring(root):
|
|
186
|
+
"""Assert .claude/settings.json wires guard_models on the Task spawn tool.
|
|
187
|
+
|
|
188
|
+
Passes when some PreToolUse group has a matcher covering the Task tool -
|
|
189
|
+
"Task" is one of its "|"-separated alternatives (the shipped matcher is
|
|
190
|
+
"Task|Agent") - and one of that group's hooks runs a command referencing
|
|
191
|
+
guard_models.py. Only the project settings.json counts; settings.local.json
|
|
192
|
+
is ignored. Returns (ok, fixit_message).
|
|
193
|
+
"""
|
|
194
|
+
fixit = (
|
|
195
|
+
"spawn enforcement is not wired: .claude/settings.json has no "
|
|
196
|
+
"PreToolUse matcher covering the Task spawn tool that runs "
|
|
197
|
+
"guard_models.py - re-run `claude-company install` or `update` to "
|
|
198
|
+
"re-add it."
|
|
199
|
+
)
|
|
200
|
+
settings = c.read_json_file(
|
|
201
|
+
os.path.join(root, ".claude", "settings.json")
|
|
202
|
+
)
|
|
203
|
+
if not isinstance(settings, dict):
|
|
204
|
+
return False, fixit
|
|
205
|
+
hooks = settings.get("hooks")
|
|
206
|
+
if not isinstance(hooks, dict):
|
|
207
|
+
return False, fixit
|
|
208
|
+
groups = hooks.get("PreToolUse")
|
|
209
|
+
if not isinstance(groups, list):
|
|
210
|
+
return False, fixit
|
|
211
|
+
for group in groups:
|
|
212
|
+
if not isinstance(group, dict):
|
|
213
|
+
continue
|
|
214
|
+
matcher = group.get("matcher") or ""
|
|
215
|
+
if "Task" not in matcher.split("|"):
|
|
216
|
+
continue
|
|
217
|
+
for h in group.get("hooks") or []:
|
|
218
|
+
if isinstance(h, dict) and "guard_models.py" in (
|
|
219
|
+
h.get("command") or ""
|
|
220
|
+
):
|
|
221
|
+
return True, ""
|
|
222
|
+
return False, fixit
|
|
223
|
+
|
|
224
|
+
|
|
127
225
|
def run_check(root):
|
|
128
|
-
"""Compare every agent frontmatter against the manifest. Exit 0/1.
|
|
226
|
+
"""Compare every agent frontmatter against the manifest. Exit 0/1.
|
|
227
|
+
|
|
228
|
+
FR-MRA-06: this frontmatter/agent-file comparison is based ONLY on `roles`.
|
|
229
|
+
Built-in types live in the separate `builtins` section and never demand a
|
|
230
|
+
.claude/agents/<type>.md file, so their absence is never a mismatch here.
|
|
231
|
+
"""
|
|
129
232
|
roles = load_manifest(root)
|
|
130
233
|
if roles is None:
|
|
131
234
|
print("company/models.json missing or unreadable")
|
|
@@ -178,6 +281,19 @@ def run_check(root):
|
|
|
178
281
|
print("\nmismatches:")
|
|
179
282
|
for m in mismatches:
|
|
180
283
|
print(" - " + m)
|
|
284
|
+
|
|
285
|
+
# LOUD wiring assertion (FR-MRA-07), gated on builtins presence.
|
|
286
|
+
# OQ-MRA-04 assumption: guard_models asserts only its OWN enforcement
|
|
287
|
+
# wiring. Old manifests without a `builtins` section (load_builtins ->
|
|
288
|
+
# None) skip this entirely and behave exactly as before.
|
|
289
|
+
wiring_ok = True
|
|
290
|
+
if load_builtins(root) is not None:
|
|
291
|
+
wiring_ok, fixit = check_spawn_wiring(root)
|
|
292
|
+
if not wiring_ok:
|
|
293
|
+
print("\nspawn wiring:")
|
|
294
|
+
print(" - " + fixit)
|
|
295
|
+
|
|
296
|
+
if mismatches or not wiring_ok:
|
|
181
297
|
return 1
|
|
182
298
|
print("\nall agent models agree with company/models.json")
|
|
183
299
|
return 0
|
|
@@ -206,7 +322,7 @@ def main():
|
|
|
206
322
|
if roles is None:
|
|
207
323
|
sys.exit(0) # no manifest -> fail open
|
|
208
324
|
if tool_name in ("Task", "Agent"):
|
|
209
|
-
handle_spawn(root, tool_input, roles)
|
|
325
|
+
handle_spawn(root, tool_input, roles, load_builtins(root))
|
|
210
326
|
elif tool_name in ("Edit", "Write", "MultiEdit"):
|
|
211
327
|
handle_frontmatter_edit(root, tool_name, tool_input, roles)
|
|
212
328
|
except SystemExit:
|
package/.claude/settings.json
CHANGED
package/ORCHESTRATOR.md
CHANGED
|
@@ -178,6 +178,11 @@ building agents into isolated worktrees:
|
|
|
178
178
|
git worktree add .claude/worktrees/<task-slug> -b task/<task-slug>
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
+
The Workflow tool is FORBIDDEN by default: its internal `agent()` spawns fire no
|
|
182
|
+
PreToolUse events, so `guard_models` cannot pin their model - permit it only
|
|
183
|
+
with explicit owner authorization and a `model` pin in every `agent()` call,
|
|
184
|
+
including all early stages (see `company/METHOD.md`).
|
|
185
|
+
|
|
181
186
|
Skeleton for a tech-lead (adapt for direct developer dispatch on `quick`):
|
|
182
187
|
|
|
183
188
|
```
|
package/company/GATES.md
CHANGED
|
@@ -65,7 +65,9 @@ These rungs are wired for this repo; a project inherits them and adds its own.
|
|
|
65
65
|
- **G7 models (`python3 .claude/hooks/guard_models.py --check`).** The model
|
|
66
66
|
routing manifest and agent frontmatter must agree: spawn overrides and
|
|
67
67
|
per-agent model declarations match `models.json`, so no agent silently runs
|
|
68
|
-
on the wrong model.
|
|
68
|
+
on the wrong model. It also asserts the Task|Agent spawn hook is wired into
|
|
69
|
+
`.claude/settings.json`, so the enforcement cannot ship as code without teeth.
|
|
70
|
+
(Shipped in wave 1.)
|
|
69
71
|
- **G8 audit - the last rung, network-bound.** A dependency and CVE scan: no
|
|
70
72
|
known-vulnerable dependency ships. It runs last because it reaches the
|
|
71
73
|
network; keep it blocking anyway.
|
package/company/METHOD.md
CHANGED
|
@@ -163,6 +163,16 @@ All under `company/state/`, all owned by the CEO:
|
|
|
163
163
|
6. Business-policy open questions. Agents run on tagged fallbacks; the owner
|
|
164
164
|
answers the question.
|
|
165
165
|
|
|
166
|
+
## The Workflow tool is outside enforcement
|
|
167
|
+
|
|
168
|
+
The Workflow tool runs its own internal `agent()` spawns that fire NO PreToolUse
|
|
169
|
+
events - the hooks never see them, so `guard_models` cannot pin their model and
|
|
170
|
+
they inherit the main-loop model. It is therefore FORBIDDEN by default in
|
|
171
|
+
company projects. It is permitted only with explicit owner authorization AND a
|
|
172
|
+
`model` pin in EVERY `agent()` call, including all early-stage agents: resuming
|
|
173
|
+
a dead workflow re-runs the incomplete early-stage agents live, so partial
|
|
174
|
+
pinning does not hold.
|
|
175
|
+
|
|
166
176
|
## Writing discipline
|
|
167
177
|
|
|
168
178
|
All writing in this repository stays hook-clean: straight quotes, ' - ' rather
|
package/company/models.json
CHANGED
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
"security-reviewer": "opus", "devops-engineer": "opus",
|
|
8
8
|
"docs-librarian": "opus", "ideation-strategist": "opus"
|
|
9
9
|
},
|
|
10
|
+
"builtins": {
|
|
11
|
+
"$comment": "Built-in agent types (Explore, general-purpose, Plan, claude) have no .claude/agents frontmatter pin, so a bare spawn silently inherits the SESSION model - guard_models therefore requires an explicit matching model override for these. The Workflow tool is hook-invisible (its agent() spawns fire no PreToolUse events) and is forbidden by default - see company/METHOD.md.",
|
|
12
|
+
"Explore": "opus",
|
|
13
|
+
"general-purpose": "opus",
|
|
14
|
+
"Plan": "opus",
|
|
15
|
+
"claude": "opus"
|
|
16
|
+
},
|
|
10
17
|
"pricing": {
|
|
11
18
|
"$comment": "OQ-W1-01 estimate only, NOT billing truth - used by .claude/hooks/cost_capture.py for rough spend visibility in company/state/costs.log and /standup. USD per million tokens (MTok). cache_write is 1.25x input, cache_read is 0.1x input.",
|
|
12
19
|
"opus": {"input": 15, "output": 75, "cache_write": 18.75, "cache_read": 1.5}
|
|
@@ -13,4 +13,10 @@ fallbacks until a row lands here._
|
|
|
13
13
|
| 5 | 2026-07-10 | Enforcement design direction | Owner REJECTED budgets/role bans twice; approved principle-derived gates (mechanism 5 + written-record consistency) and demanded low-token injection + GitHub tracking gate | all future gate design |
|
|
14
14
|
| 6 | 2026-07-15 | cli-update delivery (update subcommand + provenance manifest, PR #57, issues #54-#56) | ACCEPTED - owner: "test it, the merge it to main"; CEO re-tested end-to-end (edit kept, .new written, deleted file restored, config untouched), merged 7726c99, integrated main verified (213 hooks + 40 CLI + 56 engine green), witnesses W-014..W-016 | CLI, installer, frozen registry |
|
|
15
15
|
| 7 | 2026-07-15 | cli-self-update delivery (update refreshes the CLI first via npx handoff, PR #60, issue #59) | ACCEPTED - owner: "push to main, then to npm"; merged a09b463, integrated main verified (213 + 57 green), witnesses W-017..W-018 | CLI driver |
|
|
16
|
-
| 8 | 2026-07-15 | Release v0.2.0 to npm (
|
|
16
|
+
| 8 | 2026-07-15 | Release v0.2.0 to npm (tag v0.2.0 at 5913374; notes: PR #57/#60 bodies) | PUBLISHED 2026-07-15 by the OWNER manually from the clean tag clone (link-based npm 2FA - publishes are always owner-manual or git-CI, never agent-run). Registry verified: dist-tags.latest 0.2.0. Semver minor | npm registry |
|
|
17
|
+
| 9 | 2026-07-15 | DevMesh migration (owner: "use claude-company on this WITHOUT breaking custom changes... preserve DevMesh specific context") | DELIVERED - umbrella root git-initialized (machinery only), primitive company ported to company/, all customizations preserved, stale docs archived (nothing deleted). Verification: invariants gate PASS, 6 frozen surfaces probe-blocked. Found+fixed upstream #67/#68 | DevMesh polyrepo |
|
|
18
|
+
| 10 | 2026-07-15 | Release v0.2.1 to npm (patch: #64 enforcer arming, #67 merger fix + field-heal, #68 record-leak) | PREPPED by CEO (bump PR + tag on merge); publish is the owner's button per standing rule (link-based 2FA). SUPERSEDED by v0.2.2 (#12) before publish - registry never received 0.2.1 | npm registry |
|
|
19
|
+
| 11 | 2026-07-22 | model-routing-arming delivery (builtins enforcement + wiring gate + migration + Workflow doctrine, PR #77, issues #74-#76) | ACCEPTED - owner: "merge everything and give command to push to npm"; CEO merged cd07fb6, integrated main verified (hooks 222 + npm 61 + engine 111 green, gates stamped), live enforcement certified (contradict/bare exit 2, match 0, dormancy probe red), witnesses W-026/W-027/W-028 | hooks, models.json, installer, doctrine |
|
|
20
|
+
| 12 | 2026-07-22 | Release v0.2.2 to npm (rolls up unpublished 0.2.1 + #77 model-routing arming) | PREPPED by CEO; owner pushed tag v0.2.2 (at ad3dda8) but publish SUPERSEDED by v0.2.3 (#14) which adds #83 - registry goes 0.2.0 -> 0.2.3 directly | npm registry |
|
|
21
|
+
| 13 | 2026-07-23 | spawn-depth-shipping delivery (CC 2.1.21 depth-1 flattening; template env + installer env merge + guards, PR #83, issues #79-#82) | ACCEPTED - owner: "merge it"; merged 6061814, CEO independent verification (224/61/123 green, merge probes, byte-identity), witness W-029 | template settings, installer, tests |
|
|
22
|
+
| 14 | 2026-07-23 | Release v0.2.3 to npm (v0.2.2 content + #83 spawn-depth) | PREPPED by CEO per owner direction ("change to v0.2.3"); owner tags v0.2.3 at the release-PR merge commit and publishes from a clean tag clone (link-based 2FA, owner-manual); notes: PR #77/#83 bodies | npm registry |
|
package/company/state/RESUME.md
CHANGED
|
@@ -14,6 +14,94 @@ witnesses/models/tests/audit. Owner acceptance recorded (DECISIONS #3).
|
|
|
14
14
|
|
|
15
15
|
## 2. Next actions, in order
|
|
16
16
|
|
|
17
|
+
00000. test-infra-fixes SHIPPED 2026-07-26 (PR #85 merged 65bd070).
|
|
18
|
+
Self-authored by the CEO in the main checkout, auditor verdict SHIP,
|
|
19
|
+
CI 9/9 green across ubuntu+macos x node 18/20/22. Integrated main
|
|
20
|
+
re-verified by the CEO: hooks 224, npm test 61/0, install 96/0, all
|
|
21
|
+
stamped. Ubuntu job log confirms `Ran 224 tests ... OK` - the 121
|
|
22
|
+
previously-invisible tests passed on their first ever CI run.
|
|
23
|
+
Two defects, both found while scoping the multi-session engagement:
|
|
24
|
+
(a) tests/hooks/run_tests.sh exec'd test_hooks.py directly, so CI ran
|
|
25
|
+
103 of 224 hook tests - the other 121, including ALL of
|
|
26
|
+
test_guard_provenance.py, never ran in CI. Now unittest discover
|
|
27
|
+
with -v (the -v preserves the per-test CI log lines that
|
|
28
|
+
unittest.main(verbosity=2) used to give).
|
|
29
|
+
(b) npm test was RED ON MAIN: tests/cli/test_cli.sh piped
|
|
30
|
+
`npm pack --dry-run --json` into JSON.parse, and npm 10.5.0 writes
|
|
31
|
+
the prepare lifecycle banner to STDOUT, so all 10 pack-manifest
|
|
32
|
+
assertions were dead (PASS 51 / FAIL 10). --silent fixes it;
|
|
33
|
+
--ignore-scripts does NOT. Auditor proved the packed file list is
|
|
34
|
+
byte-identical across npm 9/10/11 (91 files).
|
|
35
|
+
RELEASE FACTS CORRECTED 2026-07-26: v0.2.3 is ALREADY PUBLISHED on npm
|
|
36
|
+
(2026-07-25T16:17Z). Prior RESUME/STATUS claims that the registry sat
|
|
37
|
+
at 0.2.0 awaiting an owner tag were STALE - the owner had already
|
|
38
|
+
tagged and published. Registry versions: 0.1.0, 0.1.1, 0.2.0, 0.2.3.
|
|
39
|
+
Nothing needs publishing for the test-infra work: tests/ is not in the
|
|
40
|
+
pack list and company/briefs/** is excluded, so the tarball is
|
|
41
|
+
unchanged by it.
|
|
42
|
+
NEW P2 WORRY - the pack list excludes company/specs|briefs|
|
|
43
|
+
change-requests but NOT company/state, so company/state/{RESUME,STATUS,
|
|
44
|
+
WORRIES,DECISIONS}.md ship into every install. Verified against the
|
|
45
|
+
live 0.2.3 tarball: those four ARE in it. The runtime files
|
|
46
|
+
(costs.log, provenance-ledger.json, active-task.json, .cost-cursor.json,
|
|
47
|
+
gates.status) are untracked, so a CLEAN-CLONE publish leaves them out -
|
|
48
|
+
but publishing from a dirty working checkout WOULD leak them. Always
|
|
49
|
+
publish from a clean clone at the tag.
|
|
50
|
+
Next: multi-session-tasks (feature) - plan approved by the owner
|
|
51
|
+
2026-07-26 at ~/.claude/plans/flickering-painting-pony.md, core-only
|
|
52
|
+
scope. active-task.json becomes N entries; the provenance ledger stops
|
|
53
|
+
wiping itself on slug change. Phase 0 spec via product-manager first.
|
|
54
|
+
NEW P1 WORRY, directly in scope for that engagement: dispatched
|
|
55
|
+
worktree agents CANNOT COMMIT - guard_commit judges them to be on main
|
|
56
|
+
because the harness pins payload cwd to the main checkout. That turns
|
|
57
|
+
every delegated build into self-authored work needing an audit.
|
|
58
|
+
|
|
59
|
+
0000. spawn-depth-shipping SHIPPED 2026-07-23 (PR #83 merged 6061814,
|
|
60
|
+
closes #79-#82; witness W-029; brief archived pending next chore
|
|
61
|
+
pass - it is tracked at company/briefs/brief-spawn-depth-shipping.md
|
|
62
|
+
on main, move to shipped/ with the next closeout PR). CC 2.1.21
|
|
63
|
+
defaulted subagent spawn depth to 1 (flattens CEO->lead->dev);
|
|
64
|
+
template now ships env CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH="2" and
|
|
65
|
+
install/update merge env additively (user values win, non-dict env
|
|
66
|
+
replaced-safe, heredocs byte-identical 3587 chars). CEO independent
|
|
67
|
+
verification: 224/61/123 all green, own merge probes (pin "3"
|
|
68
|
+
survives, bare heals to "2"), risk low. This session armed via
|
|
69
|
+
settings.local.json; memory file spawn-depth-env-required.md saved.
|
|
70
|
+
guard_tests test_scope papercut hit a THIRD time (see WORRIES P2).
|
|
71
|
+
NOTE: not on npm until the release AFTER v0.2.2 - owner still owes
|
|
72
|
+
the v0.2.2 tag+publish (DECISIONS #12), then a v0.2.3 can carry
|
|
73
|
+
spawn-depth.
|
|
74
|
+
000. model-routing-arming SHIPPED 2026-07-22 (PR #77 merged cd07fb6,
|
|
75
|
+
closes #74-#76; acceptance DECISIONS #11; witnesses W-026 wiring
|
|
76
|
+
assertion / W-027 merge byte-identity / W-028 bare-builtin block).
|
|
77
|
+
Integrated main verified by CEO: hooks 222 OK, npm 61, update
|
|
78
|
+
engine 111, --check 0, trace 21/21 after citation fix, live
|
|
79
|
+
certification (contradict/bare exit 2, match 0; dormancy probe:
|
|
80
|
+
Task|Agent group stripped -> --check exit 1 + fix-it). Worktree
|
|
81
|
+
and task branch removed; brief+spec archived to shipped/.
|
|
82
|
+
RELEASE 0.2.2 MERGED (PR #78, merge commit ad3dda8; task
|
|
83
|
+
release-0.2.2-closeout closed; audits recorded approved after the
|
|
84
|
+
verdict-parser workaround - see WORRIES P2). Integrated main green
|
|
85
|
+
+ stamped (223/61/111), registry sealed 27/27. AWAITING OWNER
|
|
86
|
+
BUTTONS ONLY: tag v0.2.2 at ad3dda8, push tag, npm publish from a
|
|
87
|
+
clean tag clone (memory: npm-publish-owner-only; registry still on
|
|
88
|
+
0.2.0 - both 0.2.1 and 0.2.2 unpublished until then). Next chore
|
|
89
|
+
pass: archive brief-release-0.2.2-closeout.md to shipped/, file
|
|
90
|
+
the guard_provenance verdict-parser issue and the guard_tests
|
|
91
|
+
test_scope-from-main issue from WORRIES. Near-miss worth
|
|
92
|
+
remembering: a .format arg mismatch made the wrong-override path
|
|
93
|
+
fail OPEN until the live replay caught it - pinned by
|
|
94
|
+
test_builtin_spawn_wrong_override_blocked.
|
|
95
|
+
00. provenance-shipping SHIPPED 2026-07-15 (PR #65, d624cc3, closes #64;
|
|
96
|
+
witnesses W-019/W-020, 20/20): fresh installs now ship
|
|
97
|
+
company/provenance.json (enforcer armed by default); update NEVER
|
|
98
|
+
auto-arms, prints one notice line. Owner field audit found the gap.
|
|
99
|
+
PENDING OWNER BUTTON: 0.2.1 patch release to npm (0.2.0 on the
|
|
100
|
+
registry still has the gap - fresh 0.2.0 installs stay dormant).
|
|
101
|
+
Same flow as 0.2.0: bump PR, tag, owner publishes from clean tag
|
|
102
|
+
clone (memory: npm-publish-owner-only). Field guidance given: owner's
|
|
103
|
+
research repo stays disarmed until they create provenance.json after
|
|
104
|
+
Jul 28; gitignore data/ to stop stop_gate churn from training jobs.
|
|
17
105
|
0. cli-update SHIPPED 2026-07-15: PR #57 merged (7726c99, closes #54-#56),
|
|
18
106
|
owner acceptance DECISIONS #6, witnesses W-014..W-016 recorded (16/16),
|
|
19
107
|
spec+brief archived to shipped/, worktree+branch removed, integrated main
|
|
@@ -29,14 +117,17 @@ witnesses/models/tests/audit. Owner acceptance recorded (DECISIONS #3).
|
|
|
29
117
|
0c. cli-self-update SHIPPED 2026-07-15: PR #60 merged (a09b463, closes
|
|
30
118
|
#59), acceptance DECISIONS #7, witnesses W-017..W-018 (18/18),
|
|
31
119
|
integrated main 213+57 green. Worktree+branch removed.
|
|
32
|
-
0d.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
120
|
+
0d. v0.2.0 PUBLISHED to npm 2026-07-15 (DECISIONS #8): tag v0.2.0 at
|
|
121
|
+
5913374, owner published manually from the clean tag clone. FIELD
|
|
122
|
+
LESSON (memory npm-publish-owner-only.md): owner npm 2FA is
|
|
123
|
+
LINK-BASED - no OTP codes exist; publishes are ALWAYS owner-manual or
|
|
124
|
+
git-CI, agent only prepares (bump PR, tag, clean tag clone, verified
|
|
125
|
+
placeholder gates.config). NEVER publish from the working checkout -
|
|
126
|
+
local gates.config wiring fails the placeholder test. Witnesses
|
|
127
|
+
W-017/18 landed via PR #62 (fab01e1). Candidate next: publish via CI
|
|
128
|
+
workflow (owner hinted "or through git ci"), #36, #37, tarball ships
|
|
129
|
+
repo board state (P3 hygiene, install never copies it), roadmap
|
|
130
|
+
#1-#11.
|
|
40
131
|
1. delegation-enforcement SHIPPED 2026-07-10 (PR #49, f9e5dae, closes
|
|
41
132
|
#42-#47; acceptance DECISIONS #4). Close-out PR in flight if session
|
|
42
133
|
died mid-close: witnesses W-011..W-013 recorded, brief archived to
|
package/company/state/STATUS.md
CHANGED
|
@@ -3,13 +3,22 @@
|
|
|
3
3
|
_Maintained by the CEO. Updated after every dispatch, merge, and CR decision._
|
|
4
4
|
_Red stays red until proven green. Never average a status._
|
|
5
5
|
|
|
6
|
-
_Last updated: 2026-07-
|
|
6
|
+
_Last updated: 2026-07-22 - model-routing-arming SHIPPED (PR #77 merged cd07fb6, acceptance DECISIONS #11); release 0.2.2 prepped._
|
|
7
7
|
|
|
8
8
|
## Active tasks
|
|
9
9
|
|
|
10
10
|
| Task | Class | Lead/Agent | State | Gates | Notes |
|
|
11
11
|
|---|---|---|---|---|---|
|
|
12
|
-
|
|
|
12
|
+
| test-infra-fixes | quick | CEO (self, audited) | SHIPPED 2026-07-26 (PR #85 merged 65bd070) | 224 hooks + 61 CLI + 96 install green on integrated main and stamped; CI 9/9 across ubuntu+macos x node 18/20/22; ubuntu log confirms "Ran 224 tests OK" | Two one-line test-infra defects. (1) CI ran 103 of 224 hook tests - run_tests.sh exec'd test_hooks.py directly, so 121 tests incl. all of test_guard_provenance never ran in CI. (2) npm test was RED on main - pack-manifest JSON parse broken by the npm 10.5.0 prepare banner on stdout, 10 dead assertions. Blocks everything downstream: a red local gate means no stamp, no commit. |
|
|
13
|
+
| multi-session-tasks | feature | not yet dispatched | SPEC READY - awaiting tracking issues then dispatch | - | active-task.json becomes N entries in one file so parallel sessions in one checkout stop overwriting each other; provenance ledger stops wiping itself on slug change. Plan approved by owner 2026-07-26, core-only scope. Phase 0 done: company/specs/spec-multi-session-tasks.md, 31 FRs / 11 BRs / 10 OQs, all fallbacks decided. PM caught a real hole in the approved plan: "ALL over non-hotfix entries" is vacuously TRUE on an empty list, which would have silently flipped guard_spec from block to ALLOW when no task is active - FR-MST-05 orders the empty check first. |
|
|
14
|
+
| spawn-depth-shipping | quick | developer | SHIPPED 2026-07-23 (PR #83 merged 6061814, closes #79-#82) | 224 hooks + 61 CLI + 123 engine green (dev AND CEO reruns); integrated main stamped | Template ships env CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=2; install/update merge env additively (user pin survives - proven); witness W-029. NOT yet on npm - registry still 0.2.0; owner has v0.2.2 tag+publish pending, and this lands in the NEXT release after that. |
|
|
15
|
+
| release-0.2.3 | release | CEO | PUBLISHED 2026-07-25 - CLOSED | integrated main green + stamped; CI 9/9 | Registry latest = 0.2.3 (published 2026-07-25T16:17Z); tags v0.2.0-v0.2.3 all on origin. The earlier "AWAITING OWNER TAG" state was stale bookkeeping - verified 2026-07-26 against `npm view claude-company versions`. Published tarball carries company/state/{RESUME,STATUS,WORRIES,DECISIONS}.md but NOT the runtime state files. DECISIONS #12-#14. |
|
|
16
|
+
|
|
17
|
+
## Shipped (recent)
|
|
18
|
+
|
|
19
|
+
| Task | Date | Evidence |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| model-routing-arming | 2026-07-22 | PR #77 merged cd07fb6 (closes #74-#76); acceptance DECISIONS #11; witnesses W-026/W-027/W-028; live certification: builtin contradict/bare spawn exit 2, match 0, dormancy probe turns --check red; migration: builtins merge lands on install AND update automatically. |
|
|
13
22
|
|
|
14
23
|
## Wave position (programs only)
|
|
15
24
|
|
|
@@ -18,7 +27,12 @@ _Last updated: 2026-07-15 - cli-update SHIPPED (PR #57 merged 7726c99, acceptanc
|
|
|
18
27
|
| adoption program 1-3 | all | SHIPPED 2026-07-10 | PRs 27/33/34/32/35 merged; acceptance DECISIONS #3 |
|
|
19
28
|
| follow-up pair | docs-sync + adr-hardening | SHIPPED 2026-07-10 | PRs 38/39/40/41 merged; #28 + #31 closed; witnesses 10/10 on main |
|
|
20
29
|
| cli-update | single workstream | SHIPPED 2026-07-15 | PR #57 merged (7726c99, closes #54-#56); integrated main 213+40+56 green; witnesses W-014..W-016; acceptance DECISIONS #6 |
|
|
21
|
-
| cli-self-update | single workstream | SHIPPED 2026-07-15 | PR #60 merged (a09b463, closes #59); integrated main 213+57 green; witnesses W-017..W-018; acceptance DECISIONS #7 |
|
|
30
|
+
| cli-self-update | single workstream | SHIPPED 2026-07-15 | PR #60 merged (a09b463, closes #59); integrated main 213+57 green; witnesses W-017..W-018 (landed via PR #62); acceptance DECISIONS #7 |
|
|
31
|
+
| v0.2.0 npm release | release | PUBLISHED 2026-07-15 | PR #61 merged, tag v0.2.0 (5913374), owner published manually (link-based 2FA); registry latest=0.2.0; DECISIONS #8 |
|
|
32
|
+
| provenance-shipping | quick fix | SHIPPED 2026-07-15 | PR #65 merged (d624cc3, closes #64); fresh installs arm the delegation enforcer, update never auto-arms; witnesses W-019/W-020; NOTE: 0.2.0 on npm still has the gap - 0.2.1 patch release recommended (owner button) |
|
|
33
|
+
| settings-merger-fix | quick fix | SHIPPED 2026-07-15 | PR #69 merged (f17c3c4, closes #67); dedup per (matcher, command) in both engines; update HEALS broken field installs (hand-proven); witnesses W-021/W-022. DevMesh hand-patched meanwhile (its c1ecbf7) |
|
|
34
|
+
| pack-leak-fix | quick fix | SHIPPED 2026-07-15 | PR #71 merged (d714892, closes #68); record trees scaffold empty + tarball negations; seeded negative test; witnesses W-023/W-024 |
|
|
35
|
+
| devmesh-migration | consulting | DELIVERED 2026-07-15 | DevMesh polyrepo migrated to claude-company (its commits b3f0a47/7e08247/c1ecbf7): docs/team ported to company/, frozen registry live (6 surfaces probe-verified), make-gates mirrored, custom agents/skills/memory preserved, 2 upstream bugs found (#67/#68 - both now fixed) |
|
|
22
36
|
|
|
23
37
|
## Open CRs
|
|
24
38
|
|
package/company/state/WORRIES.md
CHANGED
|
@@ -9,14 +9,21 @@ wave/merge; P3 is polish._
|
|
|
9
9
|
|
|
10
10
|
| P | Worry | What (one line) | CEO logic (one line) |
|
|
11
11
|
|---|---|---|---|
|
|
12
|
+
| P1 | dispatched worktree agents cannot commit at all | guard_commit.git_cwd prefers payload cwd, which the harness pins to the MAIN checkout; a developer in .claude/worktrees/<slug> on task/<slug> is judged to be on main and blocked as "commit on protected branch". Reproduced 2026-07-26 on task/ci-test-discovery; the agent correctly refused to evade and left its work staged | The #26 git_cwd fix only helps when the session cwd really is the worktree, which is never true for a dispatched subagent. Today's workaround is the CEO committing from the main checkout on the task branch, which converts every delegated build into self-authored work needing an audit - i.e. it silently defeats the delegation economics. Candidate fix: resolve the branch from the edited file's worktree, or accept a worktree path as proof of branch. Fold into the multi-session engagement |
|
|
13
|
+
| P2 | CI npm may hide what local npm catches | tests/cli/test_cli.sh pack-manifest assertions were fully dead locally on npm 10.5.0 (prepare banner on stdout corrupts the JSON) while CI stayed green - 10 assertions were failing on main and CI never said so | Fixed via --silent in test-infra-fixes; the general lesson is that a suite passing in CI is not evidence it passes for a contributor. Candidate: pin or report the npm version in the CI log |
|
|
12
14
|
| P2 | gates.config template-vs-local tension | On the product repo itself, tracked gates.config must stay placeholder (ships to installs) so stop_gate/guard_commit need uncommitted local wiring - a papercut every session | Consider gates.local.config override in run-gates.sh; candidate issue after wave 2 |
|
|
13
15
|
| P3 | costs.log accuracy limits | Multi-model stop intervals book tokens to the last model; sub-half-cent stops log est=$0.00 | Known limits from wave-1 report; revisit if spend reporting starts driving decisions |
|
|
14
16
|
| P2 | staging stales a provenance audit | work_hash includes diff --cached, so git add AFTER the auditor pass stales the audit even with identical content | Auditor worry #2: doc the order (stage, then audit, then commit) in ORCHESTRATOR step 7 wording next doctrine touch; operational for now |
|
|
15
17
|
| P3 | git -C evades guard_commit subcmd parse | guard_commit.git_subcmd treats -C <dir> as the subcommand token, so `git -C x commit` bypasses commit gates (pre-existing, Mode C inherits) | Anti-adversary, out of doctrine scope; candidate issue against guard_commit |
|
|
16
18
|
| P3 | Mode D lacks worktree-cwd exemption | Stop close-gate block message reads wrong if a worktree session ever gets an active-task.json (moot today - file is untracked) | Auditor worry #3; per-spec (mirrors stop_gate); revisit only if worktree sessions gain task state |
|
|
17
19
|
| P2 | session_start 60-line cap can hide digest | Saturated RESUME+STATUS could truncate the active-task + execution digest lines | Lead worry P2, inherited behavior; candidate tail-reservation tweak in session_start |
|
|
20
|
+
| P1 | provenance audit verdict parser is substring-naive | guard_provenance.py:487 records the negative verdict if that literal phrase appears ANYWHERE in the audit payload - including the CEO's own dispatch prompt. Hit 3x on release-0.2.2, then a 4th time on test-infra-fixes where it BLOCKED the commit twice against two passing audits | Raised to P1: it now costs real dispatches, and the trap is near-inevitable because naming the verdict vocabulary is the natural way to prompt an auditor. PROVEN WORKAROUND: give the auditor a vocabulary that cannot poison the record (SHIP / SHIP-WITH-FIXES / HALT) and forbid it from emitting the negative token. Real fix: anchor the parse to the response's verdict line. Fold the vocabulary change into .claude/agents/auditor.md so no CEO has to remember it |
|
|
21
|
+
| P2 | SendMessage-resumed audits record no provenance | Only Task/Agent spawns fire the PostToolUse event that writes an audit into the ledger. Continuing an auditor via SendMessage produces a real audit that the ledger never sees, so the commit stays blocked and the reason looks wrong | Found on test-infra-fixes after two resumed rounds counted for nothing. Doctrine fix is cheap: a re-audit must be a fresh dispatch, never a resume. Candidate: say so in ORCHESTRATOR step 7 |
|
|
22
|
+
| P2 | guard_tests resolves test_scope from main checkout | Worktree builders cannot commit brief-granted test edits until the CEO sets test_scope in MAIN's active-task.json - has now blocked two workstreams (cli-update, model-routing-arming) | Candidate fix: resolve test_scope from the target worktree, or dispatch protocol sets it whenever a brief grants test dirs; follow-up brief |
|
|
23
|
+
| P3 | models.json merge is now a THIRD duplicated heredoc | install.sh/update.sh byte-identical coupling grew (settings, CLAUDE block, now models.json builtins) - divergence risk compounds | Same root cause as existing heredoc row; the byte-identity witness candidate (lead proposal 3) mitigates; fold into any future extraction task |
|
|
18
24
|
| P2 | update.sh duplicates install.sh merge heredocs | The three merges (settings/mcp/CLAUDE block) + CC_BLOCK are copied verbatim; a future install.sh merge change silently diverges update | cli-update lead worry; candidate fixture test asserting install and update produce identical merges; extraction forbidden this pass by additive-only brief |
|
|
19
25
|
| P3 | update spawns python3 per file (~3x/file) | ~180 spawns for 61 files - seconds today, slow at scale | Candidate manifest.py hashtree batch subcommand; not blocking |
|
|
20
26
|
| P3 | manifest emission fails open at install | lib/ or package.json missing -> no manifest, update runs bootstrap-safe forever (never clean "updated") | By design (safe); revisit only if field reports show chronic manifest-less installs |
|
|
21
27
|
| P3 | extensionless files count as source | guard_spec.is_source flags any extensionless file outside company/.claude/docs/.github (e.g. Makefile, a bare "report") - a non-code agent writing one hits the execution gate | Found in owner-requested gate probe 2026-07-15; md/json/state are proven exempt; candidate: extensionless allowlist if it ever bites |
|
|
22
28
|
| P3 | guard_tests gates md inside tests/ | Any write under a tests/ segment is blocked without test_scope regardless of extension, incl. tests/**/*.md (docs-librarian MODULE.md case) | Defensible (tests are the oracle) but extension-blind; candidate: exempt NON_SOURCE_EXT under tests/ if doc syncs start colliding |
|
|
29
|
+
| P3 | background writers stale the gate stamp | Field report 2026-07-15: a training job writing untracked non-ignored files (data/) stales work_hash every turn - stop_gate demands gate reruns | By design (.gitignore IS the ignore mechanism); candidate one-line docs FAQ: gitignore background-process output dirs |
|
package/company/witnesses.json
CHANGED
|
@@ -145,7 +145,133 @@
|
|
|
145
145
|
"regex": false,
|
|
146
146
|
"why": "Manifest byte-determinism contract: sorted keys, no clock field - the bin-vs-bare parity test depends on it",
|
|
147
147
|
"added_at": "2026-07-14T22:13:07Z"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"id": "W-017",
|
|
151
|
+
"task": "cli-self-update",
|
|
152
|
+
"file": "lib/update.js",
|
|
153
|
+
"must_contain": "if (process.env.CC_SELFUPDATE_DONE) return null;",
|
|
154
|
+
"regex": false,
|
|
155
|
+
"why": "Handoff-exactly-once loop guard: the re-exec child never re-checks the registry",
|
|
156
|
+
"added_at": "2026-07-14T23:25:27Z"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "W-018",
|
|
160
|
+
"task": "cli-self-update",
|
|
161
|
+
"file": "lib/update.js",
|
|
162
|
+
"must_contain": "if (versionCompare(latest, PKG.version) <= 0) {",
|
|
163
|
+
"regex": false,
|
|
164
|
+
"why": "Strictly-newer is the only re-exec trigger; equal or older proceeds silently with the current CLI",
|
|
165
|
+
"added_at": "2026-07-14T23:25:27Z"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"id": "W-019",
|
|
169
|
+
"task": "provenance-shipping",
|
|
170
|
+
"file": "install.sh",
|
|
171
|
+
"must_contain": "copy_if_absent \"$SRC/company/provenance.json\" \"$TARGET/company/provenance.json\"",
|
|
172
|
+
"regex": false,
|
|
173
|
+
"why": "Fresh installs ship the arming manifest - the delegation enforcer is armed by default in the field",
|
|
174
|
+
"added_at": "2026-07-15T01:01:51Z"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"id": "W-020",
|
|
178
|
+
"task": "provenance-shipping",
|
|
179
|
+
"file": "update.sh",
|
|
180
|
+
"must_contain": "note: delegation enforcer installed but disarmed - create company/provenance.json to arm",
|
|
181
|
+
"regex": false,
|
|
182
|
+
"why": "update never auto-arms - a payload refresh must not switch a project's enforcement regime",
|
|
183
|
+
"added_at": "2026-07-15T01:01:51Z"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"id": "W-021",
|
|
187
|
+
"task": "settings-merger-fix",
|
|
188
|
+
"file": "install.sh",
|
|
189
|
+
"must_contain": "have = commands_by_matcher(existing_groups) # issue-67: dedup per matcher",
|
|
190
|
+
"regex": false,
|
|
191
|
+
"why": "Settings merge dedups per (matcher, command) - reverting to command-per-event re-drops multi-matcher hook groups",
|
|
192
|
+
"added_at": "2026-07-15T10:34:04Z"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"id": "W-022",
|
|
196
|
+
"task": "settings-merger-fix",
|
|
197
|
+
"file": "update.sh",
|
|
198
|
+
"must_contain": "have = commands_by_matcher(existing_groups) # issue-67: dedup per matcher",
|
|
199
|
+
"regex": false,
|
|
200
|
+
"why": "update.sh merge block stays byte-identical to install.sh - the heal path for broken field installs depends on it",
|
|
201
|
+
"added_at": "2026-07-15T10:34:04Z"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"id": "W-023",
|
|
205
|
+
"task": "pack-leak-fix",
|
|
206
|
+
"file": "install.sh",
|
|
207
|
+
"must_contain": "\"$TARGET/company/change-requests\" # issue-68",
|
|
208
|
+
"regex": false,
|
|
209
|
+
"why": "Record trees are scaffolded empty, never copied - reverting to copy_tree_if_absent re-leaks repo records into git-clone installs",
|
|
210
|
+
"added_at": "2026-07-15T11:14:01Z"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"id": "W-024",
|
|
214
|
+
"task": "pack-leak-fix",
|
|
215
|
+
"file": "package.json",
|
|
216
|
+
"must_contain": "\"!company/briefs/**\",",
|
|
217
|
+
"regex": false,
|
|
218
|
+
"why": "Tarball belt - dropping the files-negations re-ships repo records via npm",
|
|
219
|
+
"added_at": "2026-07-15T11:14:01Z"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"id": "W-026",
|
|
223
|
+
"task": "model-routing-arming",
|
|
224
|
+
"file": ".claude/hooks/guard_models.py",
|
|
225
|
+
"must_contain": "def check_spawn_wiring",
|
|
226
|
+
"regex": false,
|
|
227
|
+
"why": "run_check wiring assertion - regression means the models gate reads green while Task|Agent enforcement is unwired (code-without-wiring)",
|
|
228
|
+
"added_at": "2026-07-22T15:23:53Z"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"id": "W-027",
|
|
232
|
+
"task": "model-routing-arming",
|
|
233
|
+
"file": "update.sh",
|
|
234
|
+
"must_contain": "BYTE-IDENTICAL to the",
|
|
235
|
+
"regex": false,
|
|
236
|
+
"why": "models.json merge heredoc coupling marker - install and update must migrate identically",
|
|
237
|
+
"added_at": "2026-07-22T15:23:53Z"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"id": "W-028",
|
|
241
|
+
"task": "model-routing-arming",
|
|
242
|
+
"file": ".claude/hooks/guard_models.py",
|
|
243
|
+
"must_contain": "inherit the session model",
|
|
244
|
+
"regex": false,
|
|
245
|
+
"why": "Bare builtin-spawn BLOCK path - regression means built-in spawns silently inherit the session model (the live incident)",
|
|
246
|
+
"added_at": "2026-07-22T15:24:05Z"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"id": "W-029",
|
|
250
|
+
"task": "spawn-depth-shipping",
|
|
251
|
+
"file": ".claude/settings.json",
|
|
252
|
+
"must_contain": "CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH",
|
|
253
|
+
"regex": false,
|
|
254
|
+
"why": "Auto-update-era guard: template must ship spawn depth 2 or every install silently flattens to depth 1 on the next Claude Code",
|
|
255
|
+
"added_at": "2026-07-22T18:50:20Z"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"id": "W-030",
|
|
259
|
+
"task": "test-infra-fixes",
|
|
260
|
+
"file": "tests/hooks/run_tests.sh",
|
|
261
|
+
"must_contain": "unittest discover",
|
|
262
|
+
"regex": false,
|
|
263
|
+
"why": "CI calls this runner; reverting to a direct exec silently drops CI from 224 hook tests back to 103 with no other symptom",
|
|
264
|
+
"added_at": "2026-07-26T17:30:00Z"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"id": "W-031",
|
|
268
|
+
"task": "test-infra-fixes",
|
|
269
|
+
"file": "tests/cli/test_cli.sh",
|
|
270
|
+
"must_contain": "--json --silent",
|
|
271
|
+
"regex": false,
|
|
272
|
+
"why": "Without --silent the npm prepare banner corrupts the pack JSON and all 10 pack-manifest assertions die as false MISSING, turning the local gate red",
|
|
273
|
+
"added_at": "2026-07-26T17:30:00Z"
|
|
148
274
|
}
|
|
149
275
|
],
|
|
150
|
-
"checksum": "
|
|
276
|
+
"checksum": "a2bf1d5ece833826945887fde2d32814011ffa242c6916cd31fa05cfab5c3d17"
|
|
151
277
|
}
|
package/docs/customizing.md
CHANGED
|
@@ -80,6 +80,8 @@ Each role is one markdown file in `.claude/agents/`. The file's frontmatter sets
|
|
|
80
80
|
|
|
81
81
|
The same file carries a `pricing` map (USD per million tokens) that `cost_capture.py` reads to estimate spend in `company/state/costs.log` and the `/standup` Spend line. Update it when your rates differ; leave a model out of it and the standup reports raw token counts for that model instead of dollars. The numbers are estimates for visibility, never a bill.
|
|
82
82
|
|
|
83
|
+
- **Arm or disarm the delegation enforcer**: `company/provenance.json` is the switch. A fresh install ships it, so the enforcer is armed by default; delete it to disarm every provenance mode (same rollout posture as `company/models.json`). An `update` never creates it - if a project lacks the file, update prints a one-line notice and leaves the enforcement regime unchanged, so refreshing the payload never silently arms a project.
|
|
84
|
+
|
|
83
85
|
Two roles are load-bearing; change them carefully. `tech-lead` is the only agent allowed to spawn other agents, and `developer` carries the working rules every builder inherits.
|
|
84
86
|
|
|
85
87
|
## Adjust the founding defaults
|