@staix/agent-hub 0.12.23 → 0.12.24
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/CHANGELOG.md +98 -0
- package/README.md +8 -3
- package/docs/addons/claude-mem.md +24 -0
- package/docs/addons/codex-plugin.md +8 -0
- package/docs/addons/dot-admit.md +8 -0
- package/docs/addons/open-code-review.md +8 -0
- package/docs/addons/ponytail.md +23 -0
- package/docs/addons/ripwire.md +22 -0
- package/docs/agent-notes/README.md +5 -0
- package/docs/agent-notes/adapters.md +8 -1
- package/docs/agent-notes/bus.md +3 -1
- package/docs/agent-notes/daemon.md +7 -1
- package/docs/agent-notes/local-worker.md +4 -2
- package/docs/agent-notes/tasks.md +4 -0
- package/docs/agent-notes/tests.md +2 -1
- package/docs/bench.md +28 -3
- package/docs/cooperbench.md +4 -0
- package/docs/data-policy.md +36 -0
- package/docs/events.md +3 -0
- package/docs/gsd-collaboration-analysis.md +48 -0
- package/docs/memory.md +231 -0
- package/docs/operations.md +651 -14
- package/docs/plans/2026-10-11-issues-109-sequential.md +81 -0
- package/docs/plans/2026-10-11-routing-evaluation-proposal.md +30 -0
- package/docs/profiles.md +57 -0
- package/docs/quickstart.md +1 -1
- package/docs/research.md +31 -1
- package/docs/roles.md +85 -0
- package/docs/sdlc.md +170 -0
- package/docs/security.md +111 -4
- package/docs/smoke.md +282 -0
- package/docs/specs/2026-09-19-agent-hub-design.md +601 -7
- package/docs/specs/2026-10-12-backlog-implementation-plan.md +186 -0
- package/docs/specs/2026-10-12-office-view-design.md +212 -0
- package/docs/text-projection.md +19 -0
- package/docs/verification/2026-10-11-acp-watch-t0.md +33 -0
- package/docs/verification/2026-10-11-agent-config-inventory.md +20 -0
- package/docs/verification/2026-10-11-jcode-peer-contract.md +27 -0
- package/docs/verification/2026-10-13-0.12.24.md +94 -0
- package/docs/verification/2026-10-13-board-phone.md +31 -0
- package/docs/verification/2026-10-13-fsmonitor-fixture-attribution.md +19 -0
- package/docs/verified.json +22 -13
- package/package.json +2 -1
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/ROLE-NOTICE.md +26 -0
- package/plugins/agent-hub/server.js +1175 -339
- package/scripts/check-docs.mjs +129 -0
- package/src/adapters/acp.ts +112 -13
- package/src/adapters/claude-channel.ts +48 -11
- package/src/adapters/codex-appserver.ts +11 -0
- package/src/adapters/jcode.ts +110 -0
- package/src/adapters/local-worker.ts +10 -7
- package/src/adapters/pi.ts +94 -20
- package/src/cli/attention.ts +60 -0
- package/src/cli/bench.ts +24 -5
- package/src/cli/board-read.ts +12 -0
- package/src/cli/console-state.ts +103 -17
- package/src/cli/console.ts +54 -8
- package/src/cli/facts-hook.ts +12 -4
- package/src/cli/help.ts +35 -9
- package/src/cli/identity.ts +18 -7
- package/src/cli/init.ts +48 -10
- package/src/cli/jcode-mcp.ts +58 -0
- package/src/cli/kimi-mcp.ts +53 -0
- package/src/cli/launch.ts +16 -1
- package/src/cli/main.ts +392 -57
- package/src/cli/memory.ts +193 -0
- package/src/cli/output.ts +45 -4
- package/src/cli/pet-config.ts +1 -0
- package/src/cli/pet.ts +83 -0
- package/src/cli/preview.ts +38 -5
- package/src/cli/status-lines.ts +1 -1
- package/src/cli/tail-render.ts +1 -0
- package/src/cli/upgrade-runtime.ts +32 -3
- package/src/cli/watch.ts +31 -0
- package/src/hub/activity.ts +53 -0
- package/src/hub/ask.ts +10 -5
- package/src/hub/bench.ts +10 -3
- package/src/hub/board.ts +222 -16
- package/src/hub/bus.ts +48 -9
- package/src/hub/citations.ts +7 -0
- package/src/hub/conductor.ts +12 -7
- package/src/hub/config-trust.ts +4 -2
- package/src/hub/crash.ts +9 -0
- package/src/hub/daemon.ts +910 -120
- package/src/hub/delivery-journal.ts +5 -0
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +12 -2
- package/src/hub/facts.ts +26 -7
- package/src/hub/git.ts +8 -2
- package/src/hub/github-import.ts +28 -0
- package/src/hub/hub-tools.ts +49 -10
- package/src/hub/inference.ts +1 -1
- package/src/hub/lifecycle-schema.ts +17 -0
- package/src/hub/listen.ts +15 -0
- package/src/hub/manager.ts +12 -5
- package/src/hub/path-policy.ts +96 -0
- package/src/hub/peer-catalog.ts +28 -0
- package/src/hub/permission-mode.ts +19 -5
- package/src/hub/planning.ts +70 -0
- package/src/hub/profiles.ts +74 -0
- package/src/hub/projected-diff.ts +73 -0
- package/src/hub/projection-exec.ts +24 -0
- package/src/hub/research.ts +144 -21
- package/src/hub/roles.ts +123 -0
- package/src/hub/roster.ts +23 -0
- package/src/hub/routing.ts +18 -5
- package/src/hub/sdlc-queue.ts +112 -0
- package/src/hub/sdlc-release.ts +125 -0
- package/src/hub/sdlc.ts +250 -0
- package/src/hub/settings.ts +34 -15
- package/src/hub/shipped-roles.ts +25 -0
- package/src/hub/snapshots.ts +89 -15
- package/src/hub/start-mode.ts +7 -5
- package/src/hub/supervision.ts +1 -0
- package/src/hub/task-sweep.ts +1 -1
- package/src/hub/tasks.ts +892 -87
- package/src/hub/text-projection.ts +126 -0
- package/src/hub/tooling.ts +159 -0
- package/src/hub/ui.ts +16 -2
- package/src/hub/workflow.ts +71 -0
- package/src/local/sandbox.ts +6 -4
- package/src/local/tools.ts +11 -6
- package/src/memory/brief.ts +28 -14
- package/src/memory/import.ts +55 -0
- package/src/memory/recall.ts +84 -0
- package/src/memory/store.ts +750 -0
- package/src/memory/sync.ts +145 -0
- package/src/pet/NOTICE.md +10 -0
- package/src/pet/characters.ts +1438 -0
- package/src/pet/config.ts +31 -0
- package/src/pet/frame.ts +17 -0
- package/src/pet/pixels.ts +28 -0
- package/src/role-text.d.ts +1 -0
- package/src/ui/index.html +842 -46
- package/src/ui/needs.ts +58 -0
- package/src/ui/office-model.ts +440 -0
- package/src/ui/peer-palette.ts +16 -0
- package/src/ui/task-board.ts +49 -0
- package/src/ui/task-progress.ts +5 -1
- package/templates/AGENTS.block.md +3 -2
- package/templates/config.json +5 -1
- package/templates/profiles/dev.json +22 -0
- package/templates/profiles/general.json +26 -0
- package/templates/profiles/research.json +57 -0
- package/templates/profiles/writing.json +28 -0
- package/templates/roles/NOTICE.md +26 -0
- package/templates/roles/dev/backend-engineer.md +26 -0
- package/templates/roles/dev/code-reviewer.md +26 -0
- package/templates/roles/dev/frontend-engineer.md +26 -0
- package/templates/roles/dev/security-reviewer.md +26 -0
- package/templates/roles/dev/software-architect.md +26 -0
- package/templates/roles/dev/test-engineer.md +26 -0
- package/templates/roles/research/analyst.md +26 -0
- package/templates/roles/research/fact-checker.md +26 -0
- package/templates/roles/research/research-lead.md +26 -0
- package/templates/roles/research/researcher.md +26 -0
- package/templates/roles/research/statistician.md +26 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,104 @@ Issue and pull request numbers in the entries for 0.7.7 and earlier refer to the
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.12.24
|
|
8
|
+
|
|
9
|
+
- Preserve planner notices across queued/uncertain deliveries, stale recipient copies, queue pressure and temporary roster absence (#263).
|
|
10
|
+
- Isolate fixture-owned automatic Git maintenance without weakening document readback security assertions (#369).
|
|
11
|
+
- Keep automatic control listeners clear of requested native peer ports while preserving ownership refusals (#375).
|
|
12
|
+
|
|
13
|
+
- Restore dashboard peer role metadata and show bounded task guidance ids on board cards (#295).
|
|
14
|
+
|
|
15
|
+
- Complete terminal board column/release projections and structured late-cut/unknown approval flags (#263).
|
|
16
|
+
|
|
17
|
+
- Add bounded one-way GitHub issue intake into persistent deduplicated private-safe Backlog (#263).
|
|
18
|
+
|
|
19
|
+
- Add atomic backlog decomposition and bounded unused-child undo with staged DAGs and tool/CLI/dashboard wiring (#263).
|
|
20
|
+
|
|
21
|
+
- Add planner WIP slot admission and bounded pending-pull undo, configured capacity through existing settings, and tool/CLI/dashboard/status wiring (#263).
|
|
22
|
+
|
|
23
|
+
- Extend backlog planning with bounded acyclic dependencies and rostered reservations, retaining revision-fenced undo and unstarted-work floors (#263).
|
|
24
|
+
|
|
25
|
+
- Project shared body-free attention into the dashboard header with built-in SVG characters, accessible counts and navigation-only activation (#280).
|
|
26
|
+
|
|
27
|
+
- Add owner-approved STAIx and four alternative built-in characters, bounded mini/full footers, glyph fallback and session character cycling (#280).
|
|
28
|
+
|
|
29
|
+
- Exclude person/hub-owned work from offline-agent attention and read structural board status facts without decoding task payloads (#280).
|
|
30
|
+
|
|
31
|
+
- Add global body-free attention status, person review/offline facts, read-only recovery observation and token-free pet/prompt output (#280). Native account verification remains unverified.
|
|
32
|
+
|
|
33
|
+
- Add structural console attention counts, an ASCII STAI rule line, read-only `n` navigation, session `P`/`--no-pet`, presentation configuration and plain-mode updates (#280). Native visual checks remain unverified.
|
|
34
|
+
|
|
35
|
+
- Add revision-fenced task planning, person-owned phased release controls, actual-history dates and optional research metadata across CLI, tools and dashboard (#263).
|
|
36
|
+
|
|
37
|
+
- Import the hub's notes from claude-mem into hub memory, add optional model-suggested edges that stay out of evidence until a person confirms them, and measure memory through `memory_brief` counts, a by-memory-brief research split and `ahub bench run --memory` arms (#258, phase 3).
|
|
38
|
+
|
|
39
|
+
- Sync hub memory between a person's machines through a private git remote (`ahub memory sync`), and add long-term tasks with advisory leases and conflict display (`ahub goal`, `hub_task_propose` `goal`, status, recall and the dashboard's Long-term tasks tab) (#258, phase 2).
|
|
40
|
+
|
|
41
|
+
- Add the hub's own memory (#258, phase 1): append-only short- and long-term logs in `~/.agenthub/memory/` with a derived graph index, promotion of decision, contract and fail notes on approval, `hub_remember` `horizon` and `scope`, graph-first task briefs, recall and `ahub ask` evidence, `ahub memory`, and a read-only dashboard Memory section. PII task text and secret-looking notes never enter it.
|
|
42
|
+
|
|
43
|
+
- Add five-column dashboard task cards, ready/waiting split, shared peer colors, agent legend/lanes and scoped drag/button assignment and Backlog staging controls (#263).
|
|
44
|
+
|
|
45
|
+
- Add the Isometric projection to the dashboard Office view: the same model through the same code path with projected grid coordinates, upright labels, identical focus order and accessible names, and jump-on-switch — plus an art polish pass (outline glyphs, drawn raised hand, per-desk avatars, extruded iso desks with legs and name plates, wireframe iso rooms, Done-shelf cabinet/stacks, two-column room cards with dividers, arc arrowheads) guided by generated reference concepts kept outside the repo (#264, phase 4 of 4).
|
|
46
|
+
|
|
47
|
+
- Add optional turn/checking/links snapshot fields for the dashboard office view (exact task bubble, finishing-a-turn, check-running mark, overlap/conflict/cohort warning lines), ids-only and PII-safe with PROTOCOL and EVENTS_SCHEMA unchanged (#264, phase 3 of 4).
|
|
48
|
+
|
|
49
|
+
- Add snapshot-driven motion to the dashboard Office view: card moves by CSS transform transition, message arcs, delivery warning marks and the busy latch from event rows with timer-free keyframe fades, and the settle rule, with reduced-motion support (#264, phase 2 of 4).
|
|
50
|
+
|
|
51
|
+
- Add a static flat Office view to the dashboard: stable desks, state rooms, capped cards, an Off/Flat view control persisted in a second host-scoped cookie, and scene/list highlighting, with no daemon change (#264, phase 1 of 4).
|
|
52
|
+
|
|
53
|
+
- Record each peer's add-ons (claude-mem, ponytail, ripwire, open-code-review, the Codex plugin, dot admission) by name and version in a `tooling` event and the research records, compare tasks with each on and off (`ahub research addons`), declare and check add-on arms in `ahub bench run --addon`, and record a decision per add-on in `docs/addons/` (#248).
|
|
54
|
+
|
|
55
|
+
- Add person-only bounded merge-order and release-readiness evidence through CLI, console and both dashboard modes; retain unknown/native gates and never merge or publish from a report (#257).
|
|
56
|
+
|
|
57
|
+
- Stage unoffered Backlog tasks, reserve suggested owners, and pull/return through person-owned Tasks transitions; hide backlog from ordinary agent and conductor task reads (#263).
|
|
58
|
+
|
|
59
|
+
- Support bounded custom lifecycle stage ids, actors and entry/exit gates across Tasks, projections and managed peer schemas, preserving the approval floor (#257).
|
|
60
|
+
|
|
61
|
+
- Support bounded private/read-only data globs, real wildcard aliases and conservative discovery limits; withhold Claude scoped write grants on read-only data (#259).
|
|
62
|
+
|
|
63
|
+
- Add isolated project profile data overrides across task aliases/plans, schemas, native guidance and init while preserving flow/check authority (#259).
|
|
64
|
+
|
|
65
|
+
- Add explicit non-git shadow repositories for hub facts, snapshots and conservative undo without creating .git (#259).
|
|
66
|
+
|
|
67
|
+
- Add bounded snapshot-based rich-document review and reverse undo text previews with persistent task baselines and owned converter cleanup (#259).
|
|
68
|
+
|
|
69
|
+
- Record immutable attributed-turn catalog-role preparations in opt-in research JSONL, preserving unknown external and legacy evidence (#295).
|
|
70
|
+
|
|
71
|
+
- Add person-only catalog role assignment/clear, task role edits and Roles settings controls with pending guidance metadata (#295).
|
|
72
|
+
|
|
73
|
+
- Add validated persistent task catalog roles with bounded assignment/review guidance and identity-only records (#295).
|
|
74
|
+
|
|
75
|
+
- Add machine-local bounded read-only text projections for rich-document facts while preserving raw attribution (#259).
|
|
76
|
+
|
|
77
|
+
- Add declared private-data routing and managed local/Pi read-only data policy with hardlink-safe command bounds (#259).
|
|
78
|
+
|
|
79
|
+
- Add data-driven research/writing/general project profiles, base-class aliases, document plans and guidance while preserving dev defaults (#259).
|
|
80
|
+
|
|
81
|
+
- Add optional bounded dev/research role catalog, shipped/project hashes and MIT notices, read-only CLI diagnostics and existing session guidance paths; preserve default contracts and authority (#295).
|
|
82
|
+
|
|
83
|
+
- Add opt-in gsd-lite phase checklist guidance over existing board dependencies, reviewer-owned hashed receipts, head-bound approval blockers and read-only state/config exports (#257).
|
|
84
|
+
|
|
85
|
+
- Add person-only `ahub watch kimi|qwen` for bounded, transient headless ACP activity, private-turn stubs and safe terminal rendering (#286). Native TUI verification remains pending.
|
|
86
|
+
|
|
87
|
+
- Add optional owned Jcode 0.94.0 daemon/ACP and project MCP bridge, with unmanaged native policy, default-off roster and explicit native recovery/tool proof limits (#332).
|
|
88
|
+
|
|
89
|
+
- Add initial opt-in SDLC artifact receipts, exact-head approval gates, bounded readbacks and stage/blocker projections; retain off defaults and mark custom/release/live work pending (#257).
|
|
90
|
+
- Add optional Qwen Code 0.25.0 ACP, off roster by default, with its own verified permission table, headless CLI/preview/stop and recovery command; keep unknown quota and native proof explicit (#256).
|
|
91
|
+
|
|
92
|
+
- Default Kimi to its own pull-only TUI, retain selectable headless ACP, exclude automatic routing to pull-only peers, and let people/conductors name reviewers with withdrawal notices. Keep project MCP changes in the person launcher and refuse unsupported TUI recovery (#316).
|
|
93
|
+
- Exclude shared .agents skills and .claude.json from scoped grants; add the person-controlled, live instruction-file protection option, off by default (#323).
|
|
94
|
+
|
|
95
|
+
- Refuse release publication on stale or nonancestor document stamps; require the release merge commit even when the tree matches green CI (#318).
|
|
96
|
+
- Cancel offline ACP permission requests and withdraw pending approvals on watchdog, offline transition and stop (#311).
|
|
97
|
+
- Check original and resolved write/edit paths before scoped Pi/local grants, including symlinked agent configuration directories (#322).
|
|
98
|
+
- Measure console fitting after tab normalization and header sanitization, preventing Events body rows from overflowing (#319).
|
|
99
|
+
- Make the pending-approval watchdog regression use controlled renewals instead of a real-time response margin (#310).
|
|
100
|
+
|
|
101
|
+
- Exclude Kimi Code project configuration under .kimi-code from scoped automatic write/edit grants, alongside the legacy .kimi policy directory (#316).
|
|
102
|
+
|
|
103
|
+
- A person can change the live peer roster through settings, the dashboard or ahub roster: removed peers stop receiving new work while their queued messages, uncertain deliveries and pauses remain available, and all open owner/reviewer roles are offered to another eligible peer; explicit off-roster messages are retained with a public notice and removal reports both moves and work that stays (#315).
|
|
104
|
+
|
|
7
105
|
## 0.12.23
|
|
8
106
|
|
|
9
107
|
- Console panels: Left and Right move between the five tabs with the digit keys' guards and resets, wrapping at both ends (a read holding only arrow sequences is that many key presses, never a paste), and the Events tab colours each row's header through the stream's own tokenizer on the same tab-flattened header, so an event reads the same in both places (body lines and command output stay plain; with colour off the panel is byte-identical); the tail no longer repeats an unchanged context reading: a context line prints when the printed percentage, freshness, source or known-ness changes for that peer, not at every report (#309).
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# agent-hub
|
|
2
2
|
|
|
3
3
|
Native multi-agent hub for one developer's machine: Claude Code, Codex, Kimi Code, Pi and a
|
|
4
|
-
hub-owned local-LLM worker collaborate as peers in independent project directories, with
|
|
4
|
+
hub-owned local-LLM worker, with optional Qwen Code and Jcode support, collaborate as peers in independent project directories, with
|
|
5
5
|
task-aware model routing (Switchyard) in front of a self-hosted gateway (OmniRoute).
|
|
6
6
|
|
|
7
|
-
Status: 0.12.
|
|
7
|
+
Status: 0.12.24, control protocol 16. Durable delivery records distinguish queued
|
|
8
8
|
work from uncertain execution. The [smoke checklist](docs/smoke.md) records
|
|
9
9
|
verified paths and remaining prerequisites.
|
|
10
10
|
|
|
@@ -13,6 +13,11 @@ reconciliation, and the staged upgrade command for supported source protocols.
|
|
|
13
13
|
Controlled recovery preserves work; uncertain effects are never automatically
|
|
14
14
|
replayed and may require operator review.
|
|
15
15
|
|
|
16
|
+
[Hub memory](docs/memory.md) keeps optional local short- and long-term notes with
|
|
17
|
+
a rebuildable graph index. It runs alongside native claude-mem capture/recall,
|
|
18
|
+
which remains a separate service. Machine sync requires a configured remote;
|
|
19
|
+
no remote is created by startup.
|
|
20
|
+
|
|
16
21
|
## Start here
|
|
17
22
|
|
|
18
23
|
Requires [Bun](https://bun.sh) >=1.3.0 on PATH; Node alone cannot run the CLI.
|
|
@@ -28,7 +33,7 @@ cd <your project> && ahub init && ahub up
|
|
|
28
33
|
Or install the same version from GitHub:
|
|
29
34
|
|
|
30
35
|
```bash
|
|
31
|
-
bun add -g github:STAIxBWLB/agent-hub#v0.12.
|
|
36
|
+
bun add -g github:STAIxBWLB/agent-hub#v0.12.24 && ahub setup
|
|
32
37
|
```
|
|
33
38
|
|
|
34
39
|
The installed commands remain `ahub` and `agent-hub`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# claude-mem: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
## What it does to collaboration
|
|
6
|
+
|
|
7
|
+
- Recall: `context/inject` at session start (native hooks for Claude and Codex, the hub's `recallFor` for the other peers) and the task brief on handoff (`search` plus `timeline`).
|
|
8
|
+
- Capture: native hooks record tool use; the hub captures the local worker's (`src/memory/capture.ts`).
|
|
9
|
+
- Shared notes: `hub_remember` and the hub's own notes on done, review, escalation and checkpoint.
|
|
10
|
+
|
|
11
|
+
## Evidence
|
|
12
|
+
|
|
13
|
+
- Field data: no research records on the development machine yet (`~/.agenthub/research` empty); records written from now on carry the `tooling` fingerprint (`ahub research addons`).
|
|
14
|
+
- Controlled arms: none run. Owed: `all-on`, `claude-mem-off`, `all-off` (docs/bench.md, Add-on arms), listed in docs/smoke.md.
|
|
15
|
+
|
|
16
|
+
## Decision
|
|
17
|
+
|
|
18
|
+
| Part | Decision | Basis |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Recall at session start | keep optional | no measurement; the hub already reaches every peer through `recallFor` |
|
|
21
|
+
| Capture of tool use | keep optional | no measurement; capture runs through a cloud observer, so PII rules keep it out of PII work regardless |
|
|
22
|
+
| Long-term store, tiers, graph of notes | adopted natively in #258 | the user's request for cross-project and cross-machine memory, not a measured effect; #258 AC11 measures it (memory off, claude-mem only, native graph) |
|
|
23
|
+
|
|
24
|
+
Revisit when an arm comparison has at least 5 attempts per arm and measure, or field data has 5 tasks on each side.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Codex plugin for Claude Code: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
- What it does: lets a Claude session hand diagnosis, a second implementation or an adversarial review to Codex outside the hub's bus.
|
|
6
|
+
- Expected effects to measure: tokens and wall time per approved task, first-pass rate, and work that bypasses the task board.
|
|
7
|
+
- Evidence: none collected; the fingerprint records it for Claude only. Arms owed: `all-on`, `codex-plugin-off`, `all-off`.
|
|
8
|
+
- Decision: keep optional. The hub's own Codex peer and task board already carry delegation natively; nothing is adopted without data.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# dot admission: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
- What it does: admits heavy local work (builds, full test runs, installs) one per repository and defers under host pressure.
|
|
6
|
+
- Expected effects to measure: check failures and wall time per approved task, and checks deferred rather than run.
|
|
7
|
+
- Evidence: none collected; the fingerprint records it for every peer whose first `dot` on PATH is the dotfiles CLI. Arms owed: `all-on`, `dot-admit-off`, `all-off`.
|
|
8
|
+
- Decision: keep optional. The hub runs one completion check at a time already; admission across sessions stays the workspace's tool.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# open-code-review: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
- What it does: the OCR delegation gate selects files and rules for a review that the host agent then performs; in this workspace it gates merges.
|
|
6
|
+
- Expected effects to measure: review rounds and reviewer unmet items per approved task, `regressed` and `reverted` labels after approval.
|
|
7
|
+
- Evidence: none collected; the fingerprint records it for Claude (plugin) only. Arms owed: `all-on`, `open-code-review-off`, `all-off`.
|
|
8
|
+
- Decision: keep optional. The hub's reviewer role and review checklists (#35) are the native counterpart; no part is adopted without data.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ponytail: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
## What it does to collaboration
|
|
6
|
+
|
|
7
|
+
- A Claude Code (and optionally Codex) plugin that steers the agent toward the smallest change that works: reuse before writing, stdlib before dependencies, root cause in the shared function, `ponytail:` comments on deliberate shortcuts.
|
|
8
|
+
- Expected effects to measure: diff size and files changed per task, rework (changes requested), review rounds, and whether a "smallest diff" misses sibling callers (later `regressed` labels).
|
|
9
|
+
|
|
10
|
+
## Evidence
|
|
11
|
+
|
|
12
|
+
- Field data: none yet; the fingerprint now records it for Claude and Codex.
|
|
13
|
+
- Controlled arms: none run. Owed: `all-on`, `ponytail-off`, `all-off`.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
| Part | Decision | Basis |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Diff-size rule | keep optional | no measurement |
|
|
20
|
+
| Root-cause-in-the-shared-function rule | keep optional | no measurement; candidate for a reviewer-role rubric item if the arms show fewer `regressed` labels |
|
|
21
|
+
| `ponytail:` comments on shortcuts | already native | the repository's own convention (AGENTS.md), independent of the plugin |
|
|
22
|
+
|
|
23
|
+
No native adoption without data (backlog plan R10). A follow-up issue is opened only for a part an arm shows helps.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# ripwire: decision note (#248)
|
|
2
|
+
|
|
3
|
+
Status 2026-10-12: keep optional. No measured effect yet.
|
|
4
|
+
|
|
5
|
+
## What it does to collaboration
|
|
6
|
+
|
|
7
|
+
- A call-graph CLI agents query before editing: orientation, callers and uses, impact (blast radius with test reachability) and the tests to run for a change.
|
|
8
|
+
- Where it could matter between agents: plans that name the right symbols (the hub's overlap detection compares plan paths and symbols), fewer conflicts between owners, and reviewers finding sibling callers.
|
|
9
|
+
|
|
10
|
+
## Evidence
|
|
11
|
+
|
|
12
|
+
- Field data: none yet; the fingerprint records it for every peer that has it on PATH.
|
|
13
|
+
- Controlled arms: none run. Owed: `all-on`, `ripwire-off`, `all-off`.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
| Part | Decision | Basis |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| Impact queries before a plan | keep optional | no measurement; candidate native use is symbol-level impact for overlap detection, if `ripwire-off` shows more collisions |
|
|
20
|
+
| Caller lookups during review | keep optional | no measurement |
|
|
21
|
+
|
|
22
|
+
No native adoption without data (backlog plan R10). A follow-up issue is opened only for a part an arm shows helps.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Agent note background
|
|
2
|
+
|
|
3
|
+
Human explanation. Agent instructions: the area notes in this directory.
|
|
4
|
+
|
|
5
|
+
On 2026-10-13, two PR #368 reviews found that a missing delivery id or a missing visible row could select another Queue row. The console navigation rule in daemon.md records the exact-row contract. The missing-row and ID-less secondary-delivery regression tests demonstrate both cases.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Scope: the Codex, ACP and Pi adapters and the Pi extension (turn `generation` and `activity` events), peer turn state, approvals, and the agent processes the hub spawns and stops. Read before editing `src/adapters/`, `src/pi/`, `src/hub/peers.ts`, `src/hub/permission-mode.ts`, `src/hub/tool-refusal.ts`, `src/hub/child-process.ts`, `src/hub/lifecycle.ts` (shutdown deadline), `src/hub/start-mode.ts`, `src/hub/terminal-open.ts`, `src/memory/capture.ts` (session end) or the process-tree stop in `scripts/benchmarks/teardown.ts`, or before adding a native peer.
|
|
4
4
|
|
|
5
|
+
- Kimi TUI is a pull-only WsPeer under the one kimi id, with no hub busy/watchdog/permission/quota machinery. Only the person's launcher merges or removes its project MCP entry; a daemon headless start refuses a stale entry and never edits the file. Scrub mode/channel markers from the native child; managed AGENTS instructions and tool descriptions carry the pull rules, not MCP initialize instructions.
|
|
5
6
|
- Codex: the adapter never sends its own `initialize`. It is a proxy; hub requests use negative ids and their responses must not reach the TUI.
|
|
6
7
|
- A durable Codex steer stays pending while its native turn runs. Its RPC may answer after `turn/completed`: bound unanswered replies from that turn's end, requeue a definitive late refusal, and hold a late acceptance as uncertain without attaching it to a later turn's audience (#296).
|
|
7
8
|
- Codex reports each thread it adopts, started or resumed (`onThread`, the `native_thread` event), before any turn on it starts: the upgrade planner (`codexZeroTurn` in `src/cli/upgrade-runtime.ts`, #215) gives each codex `turn_start` to the thread adopted last before it and plans a thread it saw start with no turn (and no rollout) as a fresh start.
|
|
@@ -13,7 +14,7 @@ Scope: the Codex, ACP and Pi adapters and the Pi extension (turn `generation` an
|
|
|
13
14
|
- Pi's `always` grant (#209) is keyed by `executeTool`'s tool name, never parsed from the approval title, and lives only in that Pi start's closure. Never persist it, share it with the local worker, or let the dashboard give it.
|
|
14
15
|
- Auto-approval covers the hub's own tools by exact `mcp__agent-hub__<name>` title and only ever picks `allow_once`. Identity comes from the permission request title or, when an agent titles the request with the argument JSON (Qwen), from the announced `tool_call` title bound to the call id and resolved against the session's configured MCP servers, never from payload text, a prefix or an unrelated display title. Never widen it to a prefix or replace it with an agent-selected session mode. Set Kimi `yolo`/`auto` only for its verified native identity and an operator mode; config never-ask waits for a console y, and other ACP agents stay unmanaged on fresh/resumed starts without setting/resetting modes or failing over their reported mode; refuse runtime changes until their map exists; await the advertised mode change after session new/load and before a prompt, and fail startup on refusal. Use the shared `KIMI_MODE_IDS` mapping in `src/hub/permission-mode.ts`.
|
|
15
16
|
- Permission modes (#242) are a person's and live in the daemon's memory only: `permission` and `permission_default` are console-role control messages, `ahub permission` is `console` in `classifyPeerCommand`, and no hub tool or conductor tool sets one. The dashboard and `ahub settings` set one only through `settingsSet` (`src/hub/daemon.ts`, #269), which calls `changePermission` inside `permissionChange` as the console does: never add a second path that writes `permissionModes`. Never write a runtime choice to a restart snapshot.
|
|
16
|
-
- A
|
|
17
|
+
- A headless ACP Kimi or Codex whose mode lives in the native agent joins the bus only through `reconcileNativeStart` (`src/hub/daemon.ts`): after `start()` the daemon's current mode is applied, then `bus.add` (it can drain at once), then the state `start()` reached is replayed. Every mode change runs inside `permissionChange`, one per peer at a time.
|
|
17
18
|
- Codex takes a mode as an `approvalPolicy` override on `turn/start`, and the override persists on the thread: pass the hub's and the TUI's `turn/start` alike through `applyPermissionPolicy`, and return to `ask` only by sending the captured native policy once. With none captured, refuse while the TUI is attached; never just stop sending the override. Keep the captured native policy and the restoration debt per thread (`nativeApprovalPolicies`, `overriddenApprovals`) across detach and `thread/start` or `thread/resume`; clear a debt only on a successful response to its restoring `turn/start` while the mode is `ask` (`settlePermissionRestore`), so a rejected turn keeps it. While a thread owes a restoration with a known baseline, in any mode, never replace that baseline: a `thread/resume` response and the TUI's own `turn/start` can both echo the sticky override, and the restoring turn sends the kept baseline whatever the TUI supplied. That protection is one turn: after the restoration succeeded, a policy the TUI sends is taken as the person's choice, captured and passed through, because the proxy cannot tell a repeated echo from one. A detached proxy's `clearPermissionMode` is never refused; if the native policy is unknown, return a CLI-visible note that the thread keeps its last policy. Attached refusal directs the person to close the TUI, then run `ahub permission codex ask`.
|
|
18
19
|
- An unanswered `session/set_mode` leaves the native mode unknown, not unchanged: `AcpPeer` invalidates the turn, goes offline, stops its process group and refuses further changes until restarted. Never report the old or the requested mode after a timeout.
|
|
19
20
|
- A mode grant in `piPermit` or the local worker's `permit` (`src/hub/daemon.ts`) answers as the prompt path does: allowed only while that owner is still the attached one and the call was not aborted. `ask-when-needed` covers `PI_EDIT_TOOLS` on a `grantablePath` only (path rule: `local-worker.md`).
|
|
@@ -34,3 +35,9 @@ Scope: the Codex, ACP and Pi adapters and the Pi extension (turn `generation` an
|
|
|
34
35
|
|
|
35
36
|
- After an ACP watchdog cancels a prompt on a bus without a journal, keep the peer busy with its inactivity watchdog cleared until that prompt settles; suppress its turn-scoped updates and permissions while still accepting session-bound occupancy diagnostics. Bound the wait by the existing 30 s ACP handshake deadline, go offline, never idle, with queued work retained if it expires, and revoke the wait on stop or transport loss; a durable delivery keeps its existing offline/needs_review path.
|
|
36
37
|
- ACP quota refusals use the pinned agent contract in `src/adapters/acp-quota.ts`, fenced by native identity and current turn generation. Report hard quota and require the hub's explicit pause confirmation before settling a pre-acceptance refusal as `failed_safe`; retain `needs_review` when work already started, and keep unknown refusals on the ordinary failure path. Sanitize agent refusal text before hub-written output.
|
|
38
|
+
|
|
39
|
+
- Refuse ACP permissions while offline or waiting for watchdog cancellation before consulting automatic or human approvers. Abort pending permission signals on watchdog, offline transition and stop; the daemon withdraws their registered console approvals before any late person answer. Restart creates new requests without reviving withdrawn ones (#311).
|
|
40
|
+
|
|
41
|
+
- Apply QWEN_MODE_IDS only to a production qwen025 adapter with verified qwen-code 0.25.0 native identity and advertised ids; legacy benchmark ACP stays unmanaged. Await the native acknowledgement before bus admission, preserve existing approval fences, and never map auto or plan. No Qwen quota classification exists until a pinned native refusal is observed.
|
|
42
|
+
|
|
43
|
+
- ACP `onActivity` is a closed, transient person-only projection. Never publish it through the bus, log/event writers, UI, tools or memory. Emit only for an active turn; latch private envelopes and associated PII work, including unreadable privacy state, and discard pending chunks on turn teardown. Native terminal references do not authorize filesystem/terminal RPC reads.
|
package/docs/agent-notes/bus.md
CHANGED
|
@@ -13,8 +13,10 @@ Scope: delivery, digests and condensation, reply addressing, priority and limits
|
|
|
13
13
|
- Limits admit what is sent: the envelope `newEnvelope` builds (a reply inherits its parent's sender, `digest` resolves to the originals, `capPriority` applies), never the raw `to` and priority. Admit first and build later, and implicit replies all count as broadcasts.
|
|
14
14
|
- A reply is addressed, never broadcast. An adapter that answers a delivery passes `to: replyAudience(envs)`; anything else with an `inReplyTo` inherits that envelope's sender. Leaving `to` empty fans the message out to every peer.
|
|
15
15
|
- `digest` is not a peer: addressing a reply at the envelopes the peer was handed sends it nowhere once a delivery was condensed. The bus resolves `digest` back through `lastDelivery.originals`; anything else that reads a reply's `to` has to do the same.
|
|
16
|
-
- A pull-only peer (a Claude session without channel pushes
|
|
16
|
+
- A pull-only peer (a Claude session without channel pushes or Kimi in its own TUI) is never drained; `Bus.pull` hands it what one push would take. Drain and pull share `held()` (recovery, an uncertain delivery, any pause, the lifecycle `deliveryHeld` fence) and `remember()` (so `reply_to` resolves), and a drain rechecks `deliverable()` after condensing because such a session can take the peer meanwhile. A pull is journaled `completed` in the same transaction as the bus snapshot, never `accepted`; a failed one puts back only that peer's queue and preface and never reloads the snapshot.
|
|
17
17
|
- `resolveDelivery` mutates queues in place; a refused or failed resolution puts back only that peer's queue and preface and keeps every pause. Never reload a snapshot on a live bus.
|
|
18
18
|
- `restore` takes queued work from the journal, never from the committed snapshot once the journal has state (an empty journal, revision 0, is seeded from the commit): from the commit only an empty queue key is carried over, for an offline peer whose key no delivery ever persisted (#234). Never resurrect a non-empty queue from it.
|
|
19
19
|
- The journal's owner check (`rejectLiveOwner` in `delivery-journal.ts`) judges the manifest pid with `processLiveness` and its `pidSignature`, never a bare probe (rule: `daemon.md`).
|
|
20
20
|
- A hub-native peer (Pi, the local worker) does not get to call its own message `important`: `capPriority` caps it unless the delivery it answers held an `important` envelope addressed to it. Check the delivery, not `replyParent`, which ties on hop and takes the later item. Do not bypass it by setting `priority` in the adapter.
|
|
21
|
+
|
|
22
|
+
- Routing never chooses a pull-only owner or reviewer automatically. Pass live pull-only ids and role-specific explicit naming to the pure assign function; an automatic singleton is not named. Only a honored persisted owner reservation, explicit owner nomination/claim, or authorized reviewer nomination bypasses that eligibility refusal, never roster, PII, pause or capability guards.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Daemon, control protocol and recovery
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
- Console attention navigation selects a delivery only by an exact visible row id. A missing id or row prints read-only guidance; never select by peer or fall back to the first Queue row.
|
|
4
|
+
|
|
5
|
+
Scope: the operator console, control WS and its protocol, state files, the dashboard listener and settings, the Claude channel's reconnect, `ahub setup`, git snapshots, upgrade and recovery. Read before editing `src/cli/console.ts`, `src/cli/console-state.ts`, `src/cli/attention.ts`, `src/ui/needs.ts`, `src/hub/daemon.ts`, `src/hub/ui.ts`, `src/hub/settings.ts`, `src/hub/control-client.ts`, `src/adapters/claude-channel.ts`, `src/hub/restart.ts`, `src/hub/recovery-store.ts`, `src/hub/snapshots.ts`, `src/hub/manager.ts`, `src/hub/lifecycle.ts`, `src/hub/crash.ts`, `src/hub/start-mode.ts`, `src/hub/terminal-open.ts`, `src/hub/recovery-error.ts`, `src/hub/db-timeout.ts`, `src/cli/setup.ts`, `src/cli/upgrade*.ts`, `src/cli/terminal-recovery.ts`, `src/cli/recovery-package.ts` or `src/cli/facts-hook.ts`, or before adding a native peer.
|
|
4
6
|
|
|
5
7
|
- The plugin bundle is installed apart from the daemon. Breaking a control WS message contract bumps `PROTOCOL` in `control-client.ts`; a new request answered as unknown or an optional field preserves it, as does additive optional public task metadata in `ui_snapshot` that older clients ignore (such as `deps` in #246).
|
|
6
8
|
- `peer_stop` is console-only and stops only a hub-owned headless ACP, Pi or local runtime through its adapter. Refuse native-terminal peers and recovery-held mutations; serialize with starts and permission changes, and refuse a recovery `prepare` while a stop runs. An admitted stop holds delivery through `BusOptions.deliveryHeld` before any teardown await (never a console pause that resume can undo, or a global recovery hold that blocks unrelated peers) and withdraws the peer's pending approvals before the adapter stops. A requested stop holds an in-flight delivery as `needs_review` with an ids-only stop reason, suppresses restart/escalation, and never resolves that delivery automatically.
|
|
@@ -30,3 +32,7 @@ Scope: the control WS and its protocol, state files, the dashboard listener and
|
|
|
30
32
|
- Recovery inspection uses its existing 30 s control cap for the first status read and consumes a structured busy reply without a second status probe; ordinary lifecycle probes keep their default. Treat `busy_timeout` as a ceiling for eligible waits, not a guarantee that every write waits: a WAL snapshot conflict may fail immediately. Account for synchronous 3 s hub-database waits and serial timer callbacks when choosing a timeout; several waits may consume the 30 s control margin. Never multiply the busy wait through retries or infer stopped from a shorter probe's timeout.
|
|
31
33
|
- Every `new Database(` under `src/` is followed at once by its own `PRAGMA busy_timeout` from a named `*_BUSY_TIMEOUT_MS` constant (`HUB_DB_BUSY_TIMEOUT_MS` in `src/hub/db-timeout.ts` for `hub.db`), and nothing sets `busy_timeout` again later: `test/db-busy-timeout.test.ts` reads the source and fails on any other opening idiom, so a new one extends that guard first (#303).
|
|
32
34
|
- The manager forwards a dashboard `start_peer` with the terminal provider cap (`MAX_COMMAND_MS`) plus 5 s and reports a missed deadline as `unconfirmed`, never as a failure; it recognises the deadline by the exact text `ControlClient.request` resolves with, so change the two together. The hub's terminal reopen guard and the dashboard's retry hold share `PEER_START_RETRY_MS` (`src/hub/start-mode.ts`): never give either its own number (#298).
|
|
35
|
+
|
|
36
|
+
- Use `KNOWN_PEERS` for the native catalog and `rosterAllows` for participation. Change live membership only at the authorized roster settings write or undo, applying exactly that key. Keep external ids and projects without roster settings compatible with the existing admission and lazy status rules. Fence starts and attachment before detaching or stopping a removed runtime; retain its queue, uncertain deliveries and independent pauses. Refuse removal of the conductor holder and require explicit confirmation and `--now` for an active turn.
|
|
37
|
+
|
|
38
|
+
- A Kimi one-launch TUI admission ends on its owning detach, roster removal, matched launcher cleanup or the unclaimed 30 s deadline. An old socket or launcher never clears a newer admission. Pin --mode tui in the hub-opened terminal argv.
|
|
@@ -5,7 +5,7 @@ Scope: the hub-native local worker, its tools, path guard, denylist and seatbelt
|
|
|
5
5
|
- Nothing the local worker executes may run outside `sandboxedExec`; a new tool that spawns a process goes through it, and a tool that touches a path goes through `guardPath`.
|
|
6
6
|
- The sandbox denies home reads by default (toolchain dirs, the project and its real git dir excepted) and all network, loopback included: claude-mem and the Codex app-server listen on loopback without auth. Tests that bind a local port therefore fail when the worker runs them, also with `local.bash_network: true` (the egress proxy keeps loopback closed, and the proxy variables send a test's plain-HTTP `fetch` to the proxy, which refuses it); that is the intended trade-off, and `"direct"` is the switch until 0.13.0 removes it.
|
|
7
7
|
- The seatbelt profile refuses the `.git` name itself at any depth (creation, rename, symlink, gitfile), `config` and `hooks` directly under it, `commondir` at any depth below it or below an external git dir, and `.agenthub` anywhere in the project, every name folded against the 16 code points HFS+ ignores (#270). A submodule's git dir under the common dir's `modules/` tree gets the same `config`/`hooks` refusal at the depth submodules nest, every term anchored below the discovered modules root so ancestor directories named `refs`/`config`/`hooks` neither disable nor trip the rule, and a `/refs/` or `/logs/` segment below it excludes the path so refs named `config` or `hooks` stay writable (#281); the discovered git dirs, the modules root and the components in between are also refused as directory-entry targets (rename, replace, symlink, recreate). Known residuals: a submodule whose own path holds a whole `refs` or `logs` segment (a substring, `catalogs` included, keeps the refusal — the exclusion matches whole components only), a nested repository in bare layout (the hub never runs git there; docs/security.md), folded spellings of the components between `.git` and a submodule's git dir on a volume that folds names (the 1024-byte SBPL literal cannot hold a folded path; external git dirs carry the same residual since #270), and the submodules of a repository nested inside the project (only the project's own common dir is discovered). An external git dir's `config`/`hooks` rules cover only its own children plus the hooks directory's contents: at any depth they would deny refs named `config` or `hooks` in a worktree or submodule project. The fold is a group alternation, never a character class (the seatbelt regex engine is byte-oriented and a quantifier after a multi-byte class member binds to its last byte), and every pattern keeps its `^` anchor (an unanchored starred alternation does not match). Folded literals never contain the project root: an SBPL string literal dies at 1024 bytes. The cost: `git init`, `git clone` and `git worktree add` do not run inside the sandbox, and neither do `git worktree remove`, `git worktree prune` of a stale record, `git clean -ffd` with a nested repository, `git submodule update --init` (its git dir's `config` write is refused), or `rm -rf` of a directory holding a `.git`.
|
|
8
|
-
- Every git call the hub makes outside the sandbox goes through `src/hub/git.ts` (`hubGitArgv`/`hubGitEnv`/`hubGitSync`), which keeps the repository's configuration from naming a program the hub runs (#281); a test walks all of `src/` (src/local/ included) for a direct `spawn("git"` and fails on one outside `src/hub/git.ts` and the sandboxed tool's `src/local/tools.ts`. The sandboxed `git` tool keeps its own behavior: it runs inside the sandbox. The submodule `config`/`hooks` refusal costs a submodule whose path has `hooks` as a whole component all git-dir writes (docs/security.md).
|
|
8
|
+
- Every git call the hub makes outside the sandbox goes through `src/hub/git.ts` (`hubGitArgv`/`hubGitEnv`/`hubGitSync`), which keeps the repository's configuration from naming a program the hub runs (#281); a test walks all of `src/` (src/local/ included) for a direct `spawn("git"` and fails on one outside `src/hub/git.ts` and the sandboxed tool's `src/local/tools.ts`. The sandboxed `git` tool keeps its own behavior: it runs inside the sandbox. `hubGitArgv(args, { credentials: true })` keeps the person's credential helper and is only for the repository the hub creates itself (`~/.agenthub/memory`, #258), never a project's. The submodule `config`/`hooks` refusal costs a submodule whose path has `hooks` as a whole component all git-dir writes (docs/security.md).
|
|
9
9
|
- SBPL strings go through `sbplString` (the plain `"..."` form). In the raw `#"..."` form a backslash escapes nothing, so a `"` in a path ends the literal and the whole profile fails to parse.
|
|
10
10
|
- One denylist, `src/local/deny.ts`: the path guard, the seatbelt profile and the memory filter all read it. Seatbelt sees absolute paths, so `local.deny` entries are anchored under the project root (a bare `private/` once denied all of `/private/var`).
|
|
11
11
|
- `guardPath` walks with `lstat`: `existsSync` follows symlinks, so a dangling link looked like a new file and the write landed at its target.
|
|
@@ -14,4 +14,6 @@ Scope: the hub-native local worker, its tools, path guard, denylist and seatbelt
|
|
|
14
14
|
- After a tool with side effects ran, a failed turn is reported, never redelivered.
|
|
15
15
|
- `ctx.permit` answers a `ToolApproval` (`true`, `false`, `"expired"`, `"aborted"`, #253): only `true` permits an effect, so never test it for truthiness. A tool returns `approvalError`'s text for the rest: a denial, the expiry (which tells the model not to retry) or the withdrawal. A turn that two unanswered approvals ended (`ApprovalWaitStop`; counting rule: `adapters.md`) completes its missing tool results, settles its delivery `completed` with the reason and is never handed back for replay, also when no tool had a side effect.
|
|
16
16
|
- Hub tool calls (`hub_send`, `TASK_TOOL_NAMES`, `CONDUCTOR_TOOL_NAMES`) are never passed to `capture.observe`; `Tasks` alone decides what hub tool text reaches memory (#230).
|
|
17
|
-
- A tool that asks for approval passes its name to `ctx.permit`, and `write`/`edit` also the `guardPath` result, never the model's path string: `ask-when-needed` grants
|
|
17
|
+
- A tool that asks for approval passes its name to `ctx.permit`, and `write`/`edit` also the `guardPath` result, never the model's path string: also pass the original path separately through every permit wrapper; `ask-when-needed` grants only when both the original project-relative spelling and the real path avoid protected names through `grantablePath` (`src/hub/permission-mode.ts`). `bash` and mutating `git` pass no path. After the awaited approval `write`/`edit` run `guardPath` again and refuse a target that changed (#242).
|
|
18
|
+
|
|
19
|
+
- Honor the live `protect_instruction_files` policy in scoped grants for the three instruction names; keep reads, explicit approval and never-ask unchanged. Only the settings registry writes this machine-local policy (#323).
|
|
@@ -11,3 +11,7 @@ Scope: the task flow, assignment, the state machine and the hub's MCP tools. Rea
|
|
|
11
11
|
- `taskOp` (`src/hub/daemon.ts`) lists full PII rows only when `onPrem` holds: the in-process local worker inside a PII turn (#230). Every other caller, the local worker's ordinary turns included, gets stubs.
|
|
12
12
|
- A guard in `tasks.ts` or `conductor.ts` passes `preEffect` (throws `PreEffectToolRefusal`, `src/hub/tool-refusal.ts`) only before the operation's first board or hold write; a throw after a write, a readback failure or a wrapped error stays a plain `Error` (#254). The Pi side of the rule is in `adapters.md`.
|
|
13
13
|
- Supervision reasons use structured enums, never history notes, check output or approval titles. Round signatures survive restart; later summaries count only newly joined tasks.
|
|
14
|
+
|
|
15
|
+
- Pass off-roster ids as data into `assign()` so its trace and every owner/reviewer choice share the membership filter. Refuse a manual off-roster assignment before a board write, including a reservation. Use `reassignForRoster` through the existing assignment delivery path on removal, including in-review ownership while keeping its review state; keep the old owner or reviewer when no eligible replacement exists and emit the guarded public-title notice. Preserve budget-relay behavior when sharing that implementation.
|
|
16
|
+
|
|
17
|
+
- Phase checklists are written only through Tasks.recordLifecycle by that task's reviewer/person. Validate exact current Tasks.after edges and privacy before saving; never change dependencies, accepted owners or reservations from an import. Keep verified checklist claims separate from externally read CI, and bind them to the current reviewed head. Export only derived sanitized board/config projections.
|
|
@@ -6,9 +6,10 @@ Scope: tests, fakes and the test gate. Read before adding or changing a test or
|
|
|
6
6
|
- In Bun 1.3.14 a test timeout that fires while `Bun.spawnSync` runs can start the next test inside spawnSync's own event loop, where another spawnSync then spins at full CPU for good (trigger not pinned down; see README). Bun 1.4.2 still runs the next test inside the outer spawnSync's event loop. `scripts/check.sh` runs tests with a 20 s timeout and under `scripts/hang-watch.sh`; a test that spawns and reads the process table gets a timeout of its own.
|
|
7
7
|
- The Switchyard sidecar, sandboxed commands and the MLX server get a fixed environment (`PATH`, `HOME` and their own keys), so test knobs for their fakes travel in a wrapper script or argv, not in `process.env`; native peer children inherit the hub's environment minus the agent markers (`peerChildEnv`).
|
|
8
8
|
- Bind agent identity markers explicitly in native/CLI fixture children. The full gate starts the test runner without inherited agent markers and without an `ahub claude` session's hub variables (`AGENTHUB_PROJECT_DIR`, `AGENTHUB_STATE_DIR`, `AGENTHUB_INSTANCE_ID`, `AGENTHUB_LAUNCH_ID`); a new variable a native session exports and a fixture child reads joins that `env -u` list in `scripts/check.sh`. Never weaken production marker detection to make them pass.
|
|
9
|
+
- `bunfig.toml` preloads `test/hub-home.ts`, which gives every test run (the gate and `bun test <file>` alike) a temp `AGENTHUB_HOME` unless one is set: hub memory (#258) is on with any project config, and no test may write the person's `~/.agenthub`. Do not remove it; a test that needs its own home sets and restores the variable.
|
|
9
10
|
- A free-port probe binds `hostname: "127.0.0.1"`, matching the loopback server that takes the port (#232).
|
|
10
11
|
- `ahub upgrade` without `--to` asks the registry (`npm view`) and hands a target newer than the CLI to `bun x` (#272): a test that reaches either puts a fake `npm` first on `PATH` and a recording stand-in for `process.execPath`, as `test/upgrade-cli.test.ts` does. The interactive screens are tested through a scripted `ScreenIO`; a CLI test that needs them marks `process.stdin` and `process.stdout` as terminals in a wrapper script.
|
|
11
12
|
- Cross-process fixtures wait for the consuming client to process its handshake (the channel connected diagnostic), not merely the daemon's attached/idle state. Deadline-routing fixtures hold and release responses at the fallback decision; do not place a fixed sleep between deadline fractions and assume scheduler headroom (#287). Receipt-order fixtures use the normal watchdog for ordinary I/O, trigger expiry after observed native acceptance, and await a consumed transport barrier before asserting on late results.
|
|
12
13
|
- A bounded polling wait must assert its condition after the last attempt, or document why giving up is intentional. Append-only event histories wait for a correlated closing event, not removal of the opening event. Before changing a slow wait, identify the unreached state and repair its cause (#296).
|
|
13
14
|
- A request that a test expects a stop or shutdown to cut gets its rejection handler where the request is created, never after the awaited teardown: a late `catch` races the reset and the run fails on an unhandled rejection.
|
|
14
|
-
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. Keep the
|
|
15
|
+
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. Keep the `scripts/seeds.json` cases sequential; require the same named test green before its seeded assertion fails. Seed rot, survivors, setup/compiler failures, timeout/watchdog termination and process leaks fail the gate. Never run the full seed runner from a unit test or mutate the source checkout; inspect preserved failed fixtures before removing them. CI runs this in the required Linux `seeded guards` job after the ordinary check, separately from `scripts/check.sh`.
|
package/docs/bench.md
CHANGED
|
@@ -97,9 +97,10 @@ record reads `interrupted`.
|
|
|
97
97
|
machine. Schema `agent-hub.bench/v1`:
|
|
98
98
|
|
|
99
99
|
- `run` header: suite name and SHA-256 of the suite file, arm, fingerprint (the peers attached at the start, with the requested model and
|
|
100
|
-
permission mode where the hub's status reports them: today the model for Pi only
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
permission mode where the hub's status reports them: today the model for Pi only, and each peer's add-ons by name and
|
|
101
|
+
version as `ahub research addons` detects them (docs/research.md); the SHA-256 of `routing.toml`; the
|
|
102
|
+
hub version), the declared add-on `condition` when the arm has one, task order, repeats, the runner's process.
|
|
103
|
+
- `attempt`: arm, task id, repeat, outcome, error reason, verify exit code, hub task id, start, end, duration, and, for an
|
|
103
104
|
approved task, its #247 measures (tokens, wall and active time, review rounds, changes requested, failed checks, first
|
|
104
105
|
pass, turns, files changed, models). They are read once the turns started since the task's proposal have ended (the
|
|
105
106
|
runner waits only while their peers are still busy or paused, at most 10 minutes), so the turn that approved the task is
|
|
@@ -130,6 +131,30 @@ ms, tokens, wallMs, activeMs, reviewRounds, changesRequested, checkFailed, first
|
|
|
130
131
|
The dashboard's Benchmarks section shows the latest runs with their progress (the attempt in progress, elapsed time and
|
|
131
132
|
attempts left while one runs) and, per suite with two or more arms, a bar per arm and measure with its number as text.
|
|
132
133
|
|
|
134
|
+
## Add-on arms (#248)
|
|
135
|
+
|
|
136
|
+
`--addon <name>=on|off` (repeatable; names: `claude-mem`, `ponytail`, `ripwire`, `open-code-review`, `codex-plugin`,
|
|
137
|
+
`dot-admit`) declares an arm's add-on state. Before anything is recorded or reset, the runner reads each attached peer's
|
|
138
|
+
add-ons: an add-on declared `on` must be with at least one of them and one declared `off` with none; otherwise the run is
|
|
139
|
+
refused and names the add-on. The header keeps the declaration as
|
|
140
|
+
`condition.addons`, and every attempt names its arm. The study for one add-on is its arms with every add-on on, that one
|
|
141
|
+
off, and all off, on the same suite, refs and peers, interleaved and with the task order randomized per run:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
ahub bench run ../suites/s.json --arm all-on --addon claude-mem=on --addon ponytail=on --addon ripwire=on --repeat 5
|
|
145
|
+
ahub bench run ../suites/s.json --arm ripwire-off --addon claude-mem=on --addon ponytail=on --addon ripwire=off --repeat 5
|
|
146
|
+
ahub bench run ../suites/s.json --arm all-off --addon claude-mem=off --addon ponytail=off --addon ripwire=off --repeat 5
|
|
147
|
+
ahub bench compare all-on ripwire-off all-off
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`--memory off|claude-mem|native|both` declares which memory the arm's hub runs with (#258): `off` is neither
|
|
151
|
+
claude-mem nor hub memory, `claude-mem` only claude-mem, `native` only hub memory, `both` both. The runner reads the
|
|
152
|
+
project's `memory.enabled` and `memory.native` and refuses a mismatch before anything runs; restart the hub after
|
|
153
|
+
changing them. The header keeps it as `condition.memory`.
|
|
154
|
+
|
|
155
|
+
Switching an add-on is the person's setup between runs (a plugin's `enabledPlugins` entry, PATH); the runner only
|
|
156
|
+
checks it. CooperBench (`docs/cooperbench.md`) keeps every add-on off by design, so add-on arms run here.
|
|
157
|
+
|
|
133
158
|
## A fair comparison
|
|
134
159
|
|
|
135
160
|
- Change one thing per arm (a model, a permission mode, an add-on, a routing rule) and keep the suite, the refs and the
|
package/docs/cooperbench.md
CHANGED
|
@@ -127,6 +127,10 @@ Manifest v3 run directories (headless Pi/Qwen, `protocol: native-pq-v3` in every
|
|
|
127
127
|
|
|
128
128
|
Contributions are a heuristic for possible loss, never a certificate: per agent and file, the identifiers and changed fragments its applied writes introduced (only a Claude tool call with a successful result, or a completed Codex patch, counts; a Write replaces the agent's earlier contribution and is not credited with what other agents wrote; a delete removes it; when a file is moved, every agent's contributions to it are checked at its new path) that the final tree lacks, a fragment counting as present anywhere in the file. A same-name overwrite shows as a lost fragment. Shell commands run during the task are not attributed and are counted under `coverage`, with a missing transcript or an unreadable file. Correctness comes from the official grader, for every arm.
|
|
129
129
|
|
|
130
|
+
## Routing-time prediction preregistration (#109, 2026-10-11)
|
|
131
|
+
|
|
132
|
+
The owner approved 120 controlled matched task pairs, 60 development and 60 held-out, comparing split execution of the same work units against both solo controls. The input/outcome, exclusion, unknown-value and reporting contract is [the routing evaluation preregistration](plans/2026-10-11-routing-evaluation-proposal.md). This freezes the design and sample budget, not the execution manifests: task-family/split membership, source/check hashes, native versions, profiles and warmup history must be sealed before the first scored attempt. No collection is authorized in the solo implementation session; automatic routing remains off. AC5, T3 and T4 remain open until their measured evidence and implementation gates pass.
|
|
133
|
+
|
|
130
134
|
## Preregistration (v2)
|
|
131
135
|
|
|
132
136
|
Fixed before outcomes are collected (issue #110):
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Private and read-only data paths (#259)
|
|
2
|
+
|
|
3
|
+
- Optional shared or machine-local config declares `pii.paths` and `data.readonly`, each at most 64 project-relative paths/patterns of at most 200 characters. Entries name exact paths/subtrees or bounded globs, with no command execution. Empty or absent lists preserve existing behavior. These initial policies apply at daemon start; edit config deliberately and restart to refresh them.
|
|
4
|
+
- Example: `{ "pii": { "paths": ["data/private"] }, "data": { "readonly": ["data/raw"] } }`.
|
|
5
|
+
- Matching compares declared spellings and real targets, including symlink aliases and case variants. Unknown resolution conservatively matches an active policy. Paths outside the project cannot be selected as policy entries; managed tools retain their existing project boundary.
|
|
6
|
+
|
|
7
|
+
# Private task flow
|
|
8
|
+
|
|
9
|
+
- Declared refs, plan paths and section file anchors matching pii.paths receive a hard private signal before triage, board writes, notices or memory. The task remains local-only even if ordinary pattern-based PII routing is off.
|
|
10
|
+
- Directory scopes containing a protected path are private too. Automatic facts omit configured private files even without an open private task. Public titles/views stay stubs, private envelopes stay private, and automatic notes skip memory. Newly accepted plans cannot silently add a private path to an ordinary task. Existing pattern screening and unknown verdict handling remain in force.
|
|
11
|
+
- This governs declared task paths and the managed flow. It does not contain a same-user external shell or another native peer reading arbitrary files outside its declared task.
|
|
12
|
+
|
|
13
|
+
# Read-only managed tools
|
|
14
|
+
|
|
15
|
+
- Local/Pi read operations retain access. Managed write/edit refuse protected paths before asking for approval and re-check real targets after approval. With an active read-only policy, hardlinked write targets are refused because their identity cannot be attributed safely to one declared name.
|
|
16
|
+
- Managed command execution (bash and git) becomes filesystem read-only whenever data.readonly is active. It keeps reads and stdout/stderr, allows /dev/null, and grants no project or temporary-directory writes. Commands that create output files or caches must instead return stdout or use managed write/edit for an unprotected output path. This restriction is required by the reproduced hardlink-alias bypass of path-only Seatbelt denies.
|
|
17
|
+
- The command profile and runner must both use read-only mode; the runner refuses a profile that still carries a broad project write grant. No approval or permission mode overrides the data policy. Existing network and credential boundaries stay in force.
|
|
18
|
+
- This policy controls managed local/Pi tools, not the owner or other native processes. The hub's state, receipts, explicitly configured completion checks and temporary command directory are maintained by the daemon outside the managed command.
|
|
19
|
+
|
|
20
|
+
# Evidence boundary
|
|
21
|
+
|
|
22
|
+
- Source tests cover bounded config/layers, real-path aliases, private flow before triage, public redaction, approval re-checks and managed hardlink refusal.
|
|
23
|
+
- Native macOS command tests cover direct write, parent rename, existing/new hardlinks, temporary aliases and preserved reads. Linux runs the source guards and retains its existing no-sandbox/no-command behavior.
|
|
24
|
+
- Real-account/model execution remains unverified; no live research study runs as part of this implementation. Profile converters and shadow repositories are later #259 slices.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Bounded glob policy
|
|
28
|
+
|
|
29
|
+
- `*` matches any characters within one path segment, `?` matches one character, and a whole-segment `**` matches zero or more segments. Matching includes dot names and folds case consistently with the existing exact policy. A matched directory protects its subtree. Directory task scopes are private if they can contain a future matching descendant, even before a file exists.
|
|
30
|
+
- Examples: `pii.paths = ["data/**/*.csv"]` and `data.readonly = ["data/raw-*/**"]`. Up to 16 wildcard characters per pattern. Absolute paths, parent traversal, bracket classes, braces, negation and mixed `**suffix` forms are refused. Backslashes remain literal in exact entries but are refused in glob entries; no escape syntax is interpreted.
|
|
31
|
+
- Match both declared spelling and real target. Wildcard directory/file aliases are discovered from compatible prefixes, including symlink aliases to future targets. Discovery is refreshed per decision, with no stale cached expansion. It reads at most 4096 directory entries and traverses at most 32 levels. An unreadable/dangling/cyclic/out-of-project alias or an exhausted discovery bound conservatively protects rather than declaring a path public/writable. No discovered name or policy body is logged.
|
|
32
|
+
- Managed local/Pi write/edit and private Tasks/facts use this same matcher. Existing hardlink refusal, post-approval recheck and filesystem-read-only command profile remain unchanged.
|
|
33
|
+
- Claude's managed `ask-when-needed` hook receives `ask` for a write matching data.readonly. Reads and ordinary project writes retain their existing scoped decisions. The daemon evaluates policy locally only for the current managed PreToolUse ask-when-needed write grant and sends no pattern list to the hook. PostToolUse, unavailable/ask/never-ask modes and non-write tools perform no grant-policy discovery. Explicit native approval and `never-ask` remain the person's native authority; this is scoped auto-grant filtering, not a new Claude sandbox or containment claim.
|
|
34
|
+
- The previous malformed-config fixture that refused every wildcard now refuses an unsupported bracket class; its rejection assertion is retained. New tests establish the deliberately added glob grammar, future paths, wildcard aliases/retargeting, private scopes, discovery failures and actual daemon hook replies. Native account/model consumption is unverified.
|
|
35
|
+
|
|
36
|
+
- Hardlink identity refusal precedes path matching for managed writes, including an already protected original. This keeps the refusal stable across platform-specific real-path alias choices; read access and policy-off behavior remain unchanged.
|
package/docs/events.md
CHANGED
|
@@ -25,6 +25,9 @@ marked `private: true`, and PII tasks `pii: true`.
|
|
|
25
25
|
| `progress` | `peer`, `task` (task id), `severity`, `spinning`, `exploring`, `production`: normalized tool activity dimensions for an open task; coverage differs by peer and no commands or task text are recorded |
|
|
26
26
|
| `stuck` | `peer`, `task` (task id), `category` (`repetition`, `false_progress`, `drift`, `desperation`, `capability_gap`), `streak`, `latched`: an escalation verdict; it recommends considering reassignment and never reassigns automatically |
|
|
27
27
|
| `capability` | `peer`, `state` (`verified` or `lost`), `via`: a peer's context path for facts |
|
|
28
|
+
| `memory_brief` | `peer`, `task`, `native`, `fails`, `claudeMem`: what a task brief carried, as counts (#258, docs/memory.md) |
|
|
29
|
+
| `hub_start` | `instance`: a hub run began, written once it holds its control port and before any peer can attach (a daemon that cannot bind writes none); every peer counts as detached until its next `state` event |
|
|
30
|
+
| `tooling` | `peer`, `addons` (`{ name, version }` from a closed list, version null when unknown): the add-ons a peer works with, at each attach (#248, docs/research.md) |
|
|
28
31
|
| `native_turn_end` | `peer`, `id` (an opaque hash that names the completed turn): the end of a Claude turn, recorded once the hub finds the turn its Stop hook reported completed in the native transcript (Codex's is its `turn_end`); quiescence evidence for an integration |
|
|
29
32
|
| `supervision_turn` | `peer`, `turn` (the hub turn a supervision notice was delivered into, or `supervision-<uuid>` when none was open), `tokens` (when the adapter reported any for it), `ms` (from that turn's start, or from the delivery when none was open, to its native end): a completed native turn that received supervision, which `ahub report` counts; a failed delivery or turn, a peer that went offline or a changed native session records none |
|
|
30
33
|
| `conduct` | `peer` (the conductor, or `user` when the console releases a conductor hold), `action`, `task` (when the action names or creates one), `target` (the peer an assignment, start, hold or release names): one action of the conductor that ran, the structured twin of the console's `conductor` notice. `action` is a tool name without its `hub_` prefix: a conductor tool (`status`, `task_show`, `task_assign`, `task_escalate`, `peer_start`, `peer_hold`, `peer_release`), or one of the conductor peer's own task tools, which are not conductor tools (`task_propose`, `task_accept`, `task_decline`, `task_done`, `review`, `checkpoint`, `remember`). The role-free reads and redirects (a task's owner or reviewer with `hub_task_show`, its proposer with `hub_task_assign`) record none, and neither does `hub_task_list` |
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# GSD-shaped collaboration in agent-hub (#252)
|
|
2
|
+
|
|
3
|
+
Source review: 2026-10-11, agent-hub 5647038. Recommendation: preserve the default flow; offer a bounded gsd-lite checklist/dependency presentation through #257's opt-in lifecycle. Defer a bidirectional GSD artifact bridge until it has a separately reviewed import contract and measured value.
|
|
4
|
+
|
|
5
|
+
## Evidence boundary
|
|
6
|
+
|
|
7
|
+
This is source-based analysis, not a measured claim that GSD improves quality or cost. No matched default/GSD comparison or add-on arm ran in this solo implementation. Research records (#247, docs/research.md) store task outcomes, counts, tokens and timings, not task/plan text. The #251 bench infrastructure can compare configurations on a common suite, but infrastructure existence does not provide an effect estimate.
|
|
8
|
+
|
|
9
|
+
The inspected local adapter is `/Users/yj.lee/.agents/skills/gsd-execute-phase/SKILL.md`, SHA-256 `b10610df4d9b55bdf39141cbf469525f1429cea4ae774dc4cd486520a62cae51`. Its installation revision was not recorded, so it is not asserted to equal an upstream release. Independently reviewed upstream [execute-phase command](https://github.com/gsd-build/get-shit-done/blob/bdcaab2c752d9a33a1a1ca9acf3a3c81fb991815/commands/gsd/execute-phase.md), [workflow](https://github.com/gsd-build/get-shit-done/blob/bdcaab2c752d9a33a1a1ca9acf3a3c81fb991815/get-shit-done/workflows/execute-phase.md) and [installer](https://github.com/gsd-build/get-shit-done/blob/bdcaab2c752d9a33a1a1ca9acf3a3c81fb991815/bin/install.js) at full commit `bdcaab2c752d9a33a1a1ca9acf3a3c81fb991815` establish Codex support, dependency waves and context handoff. Codex worktree isolation is explicitly refused by that workflow; support is not a blanket guarantee of runtime parity. Therefore the issue's older claim that non-Claude runtimes cannot use GSD is too broad: Codex integration exists. Kimi/Pi/local runtime coverage was not established. The skill was inspected as reference material; its delegation/autonomous workflow was not invoked.
|
|
10
|
+
|
|
11
|
+
## Benefits and costs (qualitative)
|
|
12
|
+
|
|
13
|
+
| GSD idea | Current hub mechanism | Potential value | Cost or failure boundary |
|
|
14
|
+
| --- | --- | --- | --- |
|
|
15
|
+
| Shared written plan | Issue spec plus Task.plan signatures/paths/insertion points | More consistent implementation scope and fewer context rediscoveries | Copying the issue into an independently editable PLAN creates spec drift; derive it and preserve issue precedence |
|
|
16
|
+
| Dependency waves | Tasks.after waits for approval; overlap/cohort guards already protect integration | Expose safe concurrency and explain why work waits | A whole-wave barrier can idle independent successors; use exact predecessor edges, not an unconditional global wave barrier |
|
|
17
|
+
| Goal-backward verification | sendReview already renders a per-task checklist | Catch phase-level omissions that individually passing tasks miss | A checklist is not evidence; require exact artifacts/check results and permit inconclusive findings |
|
|
18
|
+
| Durable STATE/HANDOFF | Board/history, receipts, events, #247 records | Recover human understanding of purpose and remaining work | A second writable state authority loses or duplicates work; board remains authoritative, exports are derived |
|
|
19
|
+
| Codebase map/context packets | Plans, refs, briefs, facts and native context readings | Reduce repeated discovery across peers | Maps go stale; source hashes and bounded context are needed; privacy/PII rules remain at existing boundaries |
|
|
20
|
+
| Atomic per-task commits | Repository branch/PR conventions | Reviewable rollback and clearer scope | Additional commits are not proof of independent review; immutable head and CI gates still belong to SDLC |
|
|
21
|
+
|
|
22
|
+
These are hypotheses. There are no measured first-pass, rework, regression, token, wall-time or operator-overhead differences reported here.
|
|
23
|
+
|
|
24
|
+
## Mapping and authority
|
|
25
|
+
|
|
26
|
+
- A phase maps to an issue/release slice, not a replacement spec. Its tasks are board tasks with explicit after edges; runtime-specific executors are ordinary owners under existing roles and capabilities.
|
|
27
|
+
- Verification is a reviewer task with the phase's deliverable checklist. Task approval and phase verification remain distinct; a failed phase check does not silently erase completed task history.
|
|
28
|
+
- STATE/HANDOFF are board-derived readbacks with artifact ids, current heads, pending gates and next actors. Import is a validated proposal, never an overwrite of accepted work.
|
|
29
|
+
- GSD's workspace-pinned no-auto-advance and branch-first rules are retained. This comparison grants no extra command, permission, tool, sandbox, native restart or coordinator authority.
|
|
30
|
+
- PII stays local/on campus, untrusted text is sanitized by existing output boundaries, and model-written guidance is not evidence merely because it is in a plan.
|
|
31
|
+
|
|
32
|
+
## Recommended delivery contract (specified before implementation)
|
|
33
|
+
|
|
34
|
+
The initial option is gsd-lite, off by default, implemented with #257's lifecycle rather than a second scheduler:
|
|
35
|
+
|
|
36
|
+
- `workflow: none | gsd-lite` is a data choice, with none the default. It changes guidance/presentation only unless SDLC enforcement is separately selected.
|
|
37
|
+
- Planner input is a bounded list of task ids and predecessor ids. It resolves to exact existing after edges, validates acyclic dependencies, preserves accepted owners/reservations and rejects private text on cloud surfaces. No model-generated wave bypasses Tasks.
|
|
38
|
+
- A phase reviewer checklist stores criterion ids and evidence refs. The reviewer may pass, request changes or mark an item unverified; the parent slice is not complete while a required item remains unverified.
|
|
39
|
+
- route explain, console and dashboard show the active workflow and blocking predecessor/verification gates from the same data; defaults remain unchanged.
|
|
40
|
+
- No extra STATE/PLAN/HANDOFF authority is introduced. Explicit exports contain safe derived state and source hashes. No auto-advance or autonomous merge/release.
|
|
41
|
+
|
|
42
|
+
This bounded option is covered by a dated amendment to #257 before code. A full `workflow: gsd` bridge is not recommended for implementation yet: it needs bounded import size, source/phase identity, idempotency, conflict handling, authority and PII rules defined in a separate contract. That distinction prevents calling a partial bridge done.
|
|
43
|
+
|
|
44
|
+
## Measurement plan
|
|
45
|
+
|
|
46
|
+
Use #251 on the same sealed suite, native/model/effort profiles, role set, tools, permission modes and resource limits. Compare default versus gsd-lite checklist/dependency presentation. Preregister the task-family split and attempt/token/wall-time budget; include failed/time-limited attempts, abstentions and operator interventions. Report approved-task rate, first-pass rate, rework/regressions, observed conflicts/idle time and normalized token/time measures with family-cluster intervals. Missing activity or provider costs stay unknown. #248 separately measures add-ons; they are not credited to the workflow without their own controlled condition.
|
|
47
|
+
|
|
48
|
+
No measurement was run here. AC1 is answered qualitatively and AC2 has the bounded #257 contract; #252 stays open for the built option and AC3 comparison. Native multi-agent research is outside this turn's solo/no-ahub execution.
|