@staix/agent-hub 0.12.23 → 0.12.25
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 +109 -1
- 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 +10 -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 +8 -0
- package/docs/agent-notes/tests.md +5 -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 +666 -19
- 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 +2 -2
- 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 +288 -0
- package/docs/specs/2026-09-19-agent-hub-design.md +633 -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/verification/2026-10-14-0.12.24-audit.md +123 -0
- package/docs/verification/2026-10-14-0.12.25.md +27 -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 +171 -23
- 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 +914 -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 +115 -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 +905 -89
- package/src/hub/text-projection.ts +151 -0
- package/src/hub/tooling.ts +170 -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 +757 -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/pi/extension.ts +40 -5
- package/src/role-text.d.ts +1 -0
- package/src/ui/index.html +843 -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
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Issues from #109: audit and sequential implementation
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-11. Baseline: `06fb87afbdb315d2b6d7e6455c5084b1998cb724`. Source: GitHub issue bodies and current repository, refreshed before decisions. Execution: one implementer, no ahub orchestration and no child agents.
|
|
4
|
+
|
|
5
|
+
## Inventory
|
|
6
|
+
|
|
7
|
+
125 issues numbered #109 or later: 101 already closed, 24 open. No open PR at intake. Closed issues are not reopened or reimplemented. No whole open issue is a proven duplicate: the overlaps below are scoped dependencies or superseded sections, so blanket closure would lose acceptance criteria.
|
|
8
|
+
|
|
9
|
+
## Open issue disposition
|
|
10
|
+
|
|
11
|
+
| Issue | State | Remaining contract |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| [#109](https://github.com/STAIxBWLB/agent-hub/issues/109) | Research gate | Shadow predictor shipped; current-version routing-time preregistration and held-out errors remain. Automatic rerouting stays off. |
|
|
14
|
+
| [#198](https://github.com/STAIxBWLB/agent-hub/issues/198) | Partially shipped | PR #222 shipped the fail-closed screen; AC4 live recall/precision/unknown-rate measurement remains (bound 0.90 already fixed). |
|
|
15
|
+
| [#199](https://github.com/STAIxBWLB/agent-hub/issues/199) | Partially shipped | PR #219 shipped load moves/cooldowns. AC5 mixed-workload wait measurement remains; load moves stay opt-in. |
|
|
16
|
+
| [#248](https://github.com/STAIxBWLB/agent-hub/issues/248) | Research | Tool fingerprints, preregistered arms and real measured comparisons; no fabricated results. |
|
|
17
|
+
| [#252](https://github.com/STAIxBWLB/agent-hub/issues/252) | Design | Analyze GSD against current flow and specify optional changes; overlaps #257 but has independent evidence criteria. |
|
|
18
|
+
| [#256](https://github.com/STAIxBWLB/agent-hub/issues/256) | Feature | Qwen headless peer and explicit permission map; roster defaults off. Precedes Qwen portions of #286. |
|
|
19
|
+
| [#257](https://github.com/STAIxBWLB/agent-hub/issues/257) | Feature/design | SDLC contract, head-bound reviews and opt-in enforcement. Uses #252 analysis. |
|
|
20
|
+
| [#258](https://github.com/STAIxBWLB/agent-hub/issues/258) | Feature/design | Native memory ownership amends existing architecture; store/graph before machine sync and measurement. |
|
|
21
|
+
| [#259](https://github.com/STAIxBWLB/agent-hub/issues/259) | Feature | Non-dev profiles and document checks; preserve dev defaults. Shared profile vocabulary with #295. |
|
|
22
|
+
| [#263](https://github.com/STAIxBWLB/agent-hub/issues/263) | Feature | Backlog, dashboard board, planner grooming and releases through Tasks. Supplies later #264/#295 surfaces. |
|
|
23
|
+
| [#264](https://github.com/STAIxBWLB/agent-hub/issues/264) | Feature | Static Flat SVG first, then motion, snapshot fields, Isometric, backlog/release additions after #263. |
|
|
24
|
+
| [#266](https://github.com/STAIxBWLB/agent-hub/issues/266) | Research/feature | Vendor capability proof before task execution policy and benchmark matrix; measurements remain a separate gate. |
|
|
25
|
+
| [#273](https://github.com/STAIxBWLB/agent-hub/issues/273) | Live verification | Shipped implementation follow-ups require real accounts/terminals. Keep open; PR #320 is already merged. |
|
|
26
|
+
| [#280](https://github.com/STAIxBWLB/agent-hub/issues/280) | Feature/artwork | Pure needs model and console line first. Owner-selected artwork/license and variants remain decisions; no arbitrary asset adoption. |
|
|
27
|
+
| [#285](https://github.com/STAIxBWLB/agent-hub/issues/285) | Partially shipped | Phase 1 ACP context occupancy merged in PR #294; native proof tracked in #273. Wire-log counts, quota opt-in and surfaces remain. |
|
|
28
|
+
| [#286](https://github.com/STAIxBWLB/agent-hub/issues/286) | Feature | Watch stream and Qwen launcher are distinct from native TUI. Kimi TUI portions superseded by #316; Qwen dual-output remains gated. |
|
|
29
|
+
| [#295](https://github.com/STAIxBWLB/agent-hub/issues/295) | Feature | Catalog guidance separate from authority roles; bounded role text, layer/hash and task roles. Dashboard cards wait for #263. |
|
|
30
|
+
| [#310](https://github.com/STAIxBWLB/agent-hub/issues/310) | Bug | Replace pending-approval real-time margin with controlled watchdog observations; retain mutation proof. |
|
|
31
|
+
| [#311](https://github.com/STAIxBWLB/agent-hub/issues/311) | Security bug | Reject offline ACP permission requests; abort pending approvals and fence late decisions; restart must restore normal approvals. |
|
|
32
|
+
| [#316](https://github.com/STAIxBWLB/agent-hub/issues/316) | In progress elsewhere | Existing dirty feat-316 worktree is preserved. Step 1 shipped in PR #321; remaining pull-only Kimi implementation is not complete. |
|
|
33
|
+
| [#318](https://github.com/STAIxBWLB/agent-hub/issues/318) | Release bug | Fail tag gate on stale/non-ancestor documentation stamps; merge and squash fixture proof. |
|
|
34
|
+
| [#319](https://github.com/STAIxBWLB/agent-hub/issues/319) | Rendering bug | Normalize body tabs consistently; width checks at 40/80/120 and no-tab byte preservation. |
|
|
35
|
+
| [#322](https://github.com/STAIxBWLB/agent-hub/issues/322) | Security bug | Check protected names in both lexical and resolved write paths for Pi/local; keep realPath target and explicit approval. |
|
|
36
|
+
| [#323](https://github.com/STAIxBWLB/agent-hub/issues/323) | Security option | Inventory supported project config/skill files; instruction files remain grantable by default with person-only runtime option. |
|
|
37
|
+
|
|
38
|
+
## Sequence
|
|
39
|
+
|
|
40
|
+
1. Safety and release correctness: #311, #322, #318. Small independent correctness fixes: #319 and #310. Each gets a focused regression and the repository gate.
|
|
41
|
+
2. #323 config inventory and person-only option; complete remaining #316 work only after reading and preserving its existing worktree changes. #256 Qwen peer follows; #286 headless watch and launcher reuse that peer.
|
|
42
|
+
3. #199 mixed-workload measurement and #198 live screen evaluation using the existing code and fixed recall bound; no duplicate implementation.
|
|
43
|
+
4. #252 lifecycle analysis, #257 lifecycle implementation; #259 profiles and #295 initial dev/research role catalog.
|
|
44
|
+
5. #263 backlog/releases/dashboard board; #264 office phases; #280 console attention model and approved artwork, then dashboard surfaces.
|
|
45
|
+
6. #258 store/graph, then machine sync/leases, then import and measurement.
|
|
46
|
+
7. #266 capability matrix and execution policy; #248 controlled add-on study; #109 current-version preregistration and held-out assessment. Real accounts, resource admission and independent measurement gates apply to studies.
|
|
47
|
+
8. #285 wire-log usage and budget surfaces; OAuth probe stays off unless its separate exact authorization is satisfied. #273 remains the live receipt ledger throughout.
|
|
48
|
+
|
|
49
|
+
## Completion rules
|
|
50
|
+
|
|
51
|
+
- Do not close partially shipped work, research gates or live verification on code or synthetic tests alone.
|
|
52
|
+
- Close a duplicate only when every outstanding criterion is preserved in its named survivor; no candidate meets that rule at intake.
|
|
53
|
+
- Each implemented slice records exact head, focused checks, full `scripts/check.sh` output and PR. No merge/release is implied by a green local gate.
|
|
54
|
+
- Preserve other sessions' worktrees and dirty files. This implementation uses `.worktrees/issues-109-sequential`.
|
|
55
|
+
- Source code review and measured/runtime evidence remain distinct. Unrun native legs stay unverified.
|
|
56
|
+
|
|
57
|
+
## Intake implementation receipts
|
|
58
|
+
|
|
59
|
+
- #318: local fixture history proves a release merge commit passes and an equal-tree squash fails with the named instruction; 5 documentation tests passed.
|
|
60
|
+
- #310/#311/#319/#322: focused regressions passed (8 pass, 0 fail, 10940 assertions). Journal and journal-less offline ACP, pending approval withdrawal across console/dashboard, restart, 500 ms / 2 s native delays, all protected symlink names for Pi/local, explicit approval, never-ask and ordinary symlinks covered.
|
|
61
|
+
- At intake, full repository gate and seeded guards were pending. The later merge receipts below supersede that checkpoint; native account/runtime legs remain unverified.
|
|
62
|
+
|
|
63
|
+
## Delivered receipts, 2026-10-11
|
|
64
|
+
|
|
65
|
+
The owner subsequently authorized merging verified PRs and added Jcode peer support to the scope. These slices passed exact-head Linux/macOS `scripts/check.sh` and seeded guards, had review comments/threads handled, and were merged.
|
|
66
|
+
|
|
67
|
+
| PR | Scope | Merge commit |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| #325 | #310/#311/#318/#319/#322 safety and correctness | c292591 |
|
|
70
|
+
| #326 | #323 protected config and instruction-file policy | 3809f9c |
|
|
71
|
+
| #328 | #316 pull-only Kimi TUI | 0ff40c4 |
|
|
72
|
+
| #329 | #109 approved 120-pair preregistration | d01aec5 |
|
|
73
|
+
| #330 | #252 source analysis and bounded GSD proposal | d97991a |
|
|
74
|
+
| #331 | #256 optional Qwen ACP | f745f0b |
|
|
75
|
+
| #333 | #257 initial head-bound SDLC gates | adccf91 |
|
|
76
|
+
| #334 | #332 optional owned Jcode ACP/MCP | e414611 |
|
|
77
|
+
|
|
78
|
+
- Duplicate PR #327 was closed in favour of #328. Other sessions' worktrees and unmerged recovery history were preserved.
|
|
79
|
+
- Parent #324 remains open. #109 measurement, #252 integration/measurement, #256 native proof, #257 custom stages/release/workflow, and #332 native MCP/PII/restoration proof remain partial. A merged slice does not complete its parent's unrun criteria.
|
|
80
|
+
- Next slice: #286 Part 1 in PR #335, person-only headless ACP watch. Final checks/review are pending at this documentation checkpoint. Native T0 remains explicitly unverified.
|
|
81
|
+
- Continue with #257 bounded gsd-lite/checklist guidance, then #259 profiles and #295 catalog. Later sequence and owner-only decisions remain as listed above.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Routing-time evaluation proposal for #109
|
|
2
|
+
|
|
3
|
+
Status: design preregistered on 2026-10-11 with owner approval: controlled matched task pairs, 120 pairs (60 development and 60 held-out). No study has been collected. Execution manifests, profiles and source/check hashes must be sealed before collection. Solo implementation in #324 runs no ahub-coordinated research arm.
|
|
4
|
+
|
|
5
|
+
## Approved design and remaining execution freeze
|
|
6
|
+
|
|
7
|
+
- Selected design: 120 preregistered matched work-unit pairs, 60 development and 60 held-out, with a fixed split arm recording predictions in shadow mode and both solo controls. Unit-family membership, task/check hashes, native versions, model/hook/coordination profiles and the chronological split are sealed before any scored attempt. Warmup attempts establish the minimum five past observations per peer; they are identified separately and never enter held-out scores.
|
|
8
|
+
- Ordinary-work observations may be reported separately as diagnostics. They do not replace the selected controlled design or supply its counterfactual.
|
|
9
|
+
- 120 is the approved sample budget, not a power result. Fewer than 30 valid known held-out opportunities, an invalid profile or inadequate comparability makes the result inconclusive. No retries or additional samples are selected by scores. A larger sample requires a dated amendment before collection resumes.
|
|
10
|
+
|
|
11
|
+
## Input and outcome boundary
|
|
12
|
+
|
|
13
|
+
Only a recorded `split` event with `where: routing`, made when routing first assigns an unnamed task overlapping another owner's still-proposed task, enters the prediction sample. Claims, named owners, reassignments, relays and cohort-time predictions are retained but excluded with their reason. A task's own future outcome never enters its input history.
|
|
14
|
+
|
|
15
|
+
Persist the immutable decision-time peer profiles, previous eligible observation ids, comparability/work-unit declarations, backlog, availability, verdict, assumption trace and predicted times. Failures and time-limited attempts are typed observations, not deleted survivors. Missing durations, version/hook identities and usage remain unknown.
|
|
16
|
+
|
|
17
|
+
Accept-to-first-done and assignment-to-accept are workflow stage proxies. They do not establish clean model orientation or service time. Queueing, tool/model work, approval/check time and coordination are reported separately when observable, otherwise unknown. Equal class is the current board's normalization assumption; it is not proof of equal task size.
|
|
18
|
+
|
|
19
|
+
Outcome joins happen only after terminal settlement. In the controlled design, paired split and solo durations, check outcomes, resource use and end causes are report outputs. Hidden evaluator results are applied only after outcomes are sealed and never influence forecasts, exclusions or collection order.
|
|
20
|
+
|
|
21
|
+
## Report and enablement boundary
|
|
22
|
+
|
|
23
|
+
- Report all attempted opportunities and exclusions; known/unknown/inconclusive counts; failure/censoring rates; absolute and relative stage-time errors; bias; predicted/observed gain sign confusion; and seeded, family-cluster bootstrap intervals with the seed and family count.
|
|
24
|
+
- Predeclare unknown handling. Unknown/inconclusive predictions have no numeric error and are never counted as correct. Failed/time-limited outcomes have their own table rather than an invented zero duration.
|
|
25
|
+
- The observational result cannot supply a causal team-versus-solo gain. The controlled result separately checks quality and resources against both solo controls; prediction accuracy alone cannot enable routing.
|
|
26
|
+
- Automatic rerouting remains off. This proposal does not tick AC5, complete T3, implement T4 or treat the historical equal-half calculation as a bound. This study is non-enabling regardless of its result: it reports prediction errors and paired quality/resource outcomes. Any future enablement study must preregister numerical acceptance thresholds before collecting new held-out data and obtain a separate explicit opt-in.
|
|
27
|
+
|
|
28
|
+
## Reproducibility record
|
|
29
|
+
|
|
30
|
+
The frozen preregistration goes into `docs/cooperbench.md` next to the existing v2 preregistration, per #109's dated decision. Archive the source/profile/check hashes, split membership and budget before data; publish only sanitized counts, ids and timing summaries. Native prompts, gold solutions, user task text and credentials stay out of repository materials. Resource admission and settled owner teardown apply to every live arm.
|
package/docs/profiles.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Project profiles (#259)
|
|
2
|
+
|
|
3
|
+
- `dev` remains the default. Its config/AGENTS template, flow contract, proposal-tool schema and legacy task representation retain their existing bytes/shape.
|
|
4
|
+
- `ahub init --profile research|writing|general` creates missing defaults and that profile's managed AGENTS block. Repeated init reads the existing shared profile. An explicit conflicting profile refuses before any file write; init never overwrites existing project policy. Change profile deliberately in config, then refresh instructions.
|
|
5
|
+
- Profiles are shipped data at `templates/profiles/<name>.json`: class aliases, plan keys, flow-role guidance, optional catalog ids and AGENTS text. Config role/capability/permission settings still own authority. Profile-data overrides and converters are later slices.
|
|
6
|
+
|
|
7
|
+
# Classes and plans
|
|
8
|
+
|
|
9
|
+
- Research: question=plan, survey=summarize, extract=bulk_edit, analyze=implement, synthesize=summarize, draft=implement, fact_check=test, review=review, triage=triage.
|
|
10
|
+
- Writing: outline=plan, draft=implement, edit=bulk_edit, translate=implement, fact_check=test, format=bulk_edit, review=review, summarize=summarize.
|
|
11
|
+
- General: plan=plan, do=implement, check=test, review=review, summarize=summarize, triage=triage.
|
|
12
|
+
- Existing base names remain accepted in every profile. Unknown aliases and another profile's aliases refuse before proposal effects. The board stores the base plus the selected profile/class on non-dev tasks; old rows stay unchanged. Routing, reviewer choice, budgets, outcomes and checks run on the base.
|
|
13
|
+
- Non-dev plans accept paths, sections, sources and claims. Use full section anchors such as `report.md#methods` and explicit source ids. Equal declared anchors or source ids produce overlap notices. Two document tasks naming distinct section anchors can share a file without a broad path notice; a task without section declarations still reserves the whole path. Claims are evidence ids, not overlap claims. Dev keeps its existing four plan keys.
|
|
14
|
+
- A task keeps the profile it was proposed under when accepted after a project profile change. Plans are bounded through the existing Tasks normalization and PII screen. Catalog defaults are guidance, not new flow roles; explicit per-peer catalog selections replace profile defaults, including an empty list.
|
|
15
|
+
|
|
16
|
+
# Literature review example
|
|
17
|
+
|
|
18
|
+
- Initialize a new folder with `ahub init --profile research`.
|
|
19
|
+
- Propose a survey task for three declared sources; its base is summarize. Propose extract tasks with source ids and section anchors, then synthesize after those tasks are approved.
|
|
20
|
+
- Propose fact_check with the claim ids and source map. A model labels each claim supported, unsupported or unclear. A person or deterministic check decides whether it passed; a model judgment alone never establishes verification.
|
|
21
|
+
- Configure an explicit machine-local `checks.fact_check` command if desired. Alias checks take precedence over a base `checks.test`; no check runs merely because a profile was selected.
|
|
22
|
+
- Example deterministic check: `bun /path/to/agent-hub/scripts/check-citations.ts report.md references.bib`. It checks bracketed Markdown `[@key; @other]` keys against BibTeX entry keys, with 256 KiB/4 MiB input caps. It performs no fetch, validates no source quality and is not a full Markdown/BibTeX parser. A missing key exits 1. A resolved bibliography is one check, not proof that claims are supported.
|
|
23
|
+
- Keep a person's sign-off as the final review. The live three-source/two-agent example remains unverified and was not run during solo implementation.
|
|
24
|
+
|
|
25
|
+
# General project example
|
|
26
|
+
|
|
27
|
+
- Initialize with `ahub init --profile general`.
|
|
28
|
+
- Propose plan for an event checklist, do for the agreed deliverable, and check for the declared acceptance criteria. Their bases are plan, implement and test.
|
|
29
|
+
- Name deliverable paths and section anchors before starting, then report observed outcomes and unknowns. Select `reviewer: user` through the existing routing policy when a person's decision is required.
|
|
30
|
+
|
|
31
|
+
# Current scope and remaining slices
|
|
32
|
+
|
|
33
|
+
- Peer guidance and profile-specific task schemas use existing MCP/native/local paths. Research defaults use the #295 dev/research catalog, with bases already held. Writing/general do not add catalog groups before measurement.
|
|
34
|
+
- Board/public projections, route explain, terminal/dashboard cards and #247 events/records carry the profile alias and base. Native model ingestion and context retention remain unverified.
|
|
35
|
+
- Bounded rich-document facts/review/undo projections and declared pii.paths/data.readonly policy are supported. Opt-in shadow git supports non-git folders; project profile overrides are supported; bounded glob policy and deeper lifecycle integration are tracked in #259. Native ingestion and research measurement remain unverified.
|
|
36
|
+
|
|
37
|
+
- Accept schemas expose all supported plan fields because an open task keeps its stored profile across a project profile change. Tasks still normalizes by that stored profile; no new plan field changes authority.
|
|
38
|
+
|
|
39
|
+
- Private and read-only data path policy is now a separate source slice: [data policy](data-policy.md). It applies to declared task paths and managed local/Pi tools. Bounded globs share the same private/read-only matcher; native/live follow-ups remain open.
|
|
40
|
+
|
|
41
|
+
- Optional machine-local [text projections](text-projection.md) supply bounded rich-document facts diffs. Converter output is presentation evidence and cannot prove raw-file attribution.
|
|
42
|
+
|
|
43
|
+
# Non-git folders
|
|
44
|
+
|
|
45
|
+
- Use `ahub init --profile research --shadow` to create `.agenthub/shadow.git` without a `.git` entry. `--dry-run --json` previews the same action without writes. Existing Git projects are refused for shadow opt-in; ordinary init does not select it.
|
|
46
|
+
- `.agenthub/ignore` contains owner-managed patterns for large/raw data (`data/raw/` initially). Hub snapshots and facts honor it, while runtime/local config and shadow metadata remain excluded. Models gain no permission to write hub metadata.
|
|
47
|
+
- Research/writing/general projects without Git or shadow run the hub with facts/snapshots/undo off and one notice. Legacy dev named-file facts remain supported; Git directory facts, snapshots and undo require a repository.
|
|
48
|
+
- Shadow HEAD/index are not changed by hub snapshots or raw undo. Later-edit and concurrent/unknown-turn guards still apply. Linked/shared/malformed shadow metadata is refused. Each shadow Git call revalidates descendants without following links (at most 20000 entries and 32 levels), including cached repository handles. Native model/account research runs remain unverified.
|
|
49
|
+
|
|
50
|
+
# Project profile overrides
|
|
51
|
+
|
|
52
|
+
- `profile_overrides` in shared/local config selects project data over the chosen shipped profile. `classes`, `role_text` and `catalog_roles` maps merge by key across layers; `plan_keys`, `agents` and `example_checks` replace as units. A local `profile` selects the active base for both init and native contracts.
|
|
53
|
+
- Classes may add or remap profile aliases to existing base classes. Existing base names keep their meanings; class maps are bounded to 32 override entries. Task storage and route explanations preserve the alias, including a dev custom alias, while routing/budgets/checks use its base. Other tasks under custom dev data retain the selected profile semantics too, so document sections do not become whole-path overlaps. Unmodified dev rows retain their old shape.
|
|
54
|
+
- `plan_keys` selects distinct existing plan fields, not new board fields. Task proposals and their schemas use the selection. Accept schemas retain legacy fields for already existing tasks/profile changes.
|
|
55
|
+
- `role_text` is bounded guidance for existing flow roles (2000 characters each); it grants no authority. `catalog_roles` supplies bounded compatible guidance ids; the existing explicit catalog selections take precedence. Actual flow maps remain in `roles` and retain their existing validation.
|
|
56
|
+
- `agents` replaces only the managed AGENTS block (16000 characters maximum); surrounding instructions remain. Init previews contain paths/actions only. `example_checks` is at most 16 display strings of 2000 characters, shown as advisory examples by init and never selected as executable checks. Existing `checks` trust remains authoritative.
|
|
57
|
+
- No override mutates shipped profile data or another project. Unknown fields, base remapping and invalid/oversized data are refused. Headers are quoted. Daemon/MCP restart is required for config changes; no native model consumption or research measurement is claimed.
|
package/docs/quickstart.md
CHANGED
|
@@ -17,7 +17,7 @@ ahub setup # installs the Claude Code channel plu
|
|
|
17
17
|
Or use the matching GitHub release:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
bun add -g github:STAIxBWLB/agent-hub#v0.12.
|
|
20
|
+
bun add -g github:STAIxBWLB/agent-hub#v0.12.25
|
|
21
21
|
ahub setup
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -38,7 +38,7 @@ In your project directory, one terminal each:
|
|
|
38
38
|
ahub init # .agenthub/config.json, .agenthub/routing.toml, the marker block in AGENTS.md
|
|
39
39
|
ahub up # starts the daemon and opens the operator console in a terminal
|
|
40
40
|
ahub console # use in another terminal if up used --no-console; Tab opens panels
|
|
41
|
-
ahub kimi # Kimi
|
|
41
|
+
ahub kimi # Kimi in its own pull-only TUI; --mode headless for the hub-driven peer
|
|
42
42
|
ahub codex # Codex TUI, attached through the hub
|
|
43
43
|
ahub claude # Claude Code with the hub channel
|
|
44
44
|
```
|
package/docs/research.md
CHANGED
|
@@ -48,6 +48,7 @@ while the store keeps the older records.
|
|
|
48
48
|
| `createdAt`, `startedAt`, `approvedAt` | proposal, first `in_progress`, approval (ISO) |
|
|
49
49
|
| `wallMs` | from `startedAt` to `approvedAt`, null when the start is not in the events |
|
|
50
50
|
| `activeMs`, `turns`, `filesChanged` | sums over the turns attributed to the task (`turn_end`), the ones ending after the approval included |
|
|
51
|
+
| `sessionRoles` | optional attributed-turn preamble preparations: peer, turn id, role ids/layers/hashes; `roles: []` means prepared without catalog guidance, `roles: null` means unknown; older events leave the field absent. No role bodies or proof of model consumption |
|
|
51
52
|
| `owners`, `reviewer` | the owners in the order they held the task (an owner who gets it back appears again; reports by owner count the task once per owner); the last reviewer |
|
|
52
53
|
| `reviewRounds`, `changesRequested`, `dones` | times it went to review, was sent back, was reported done |
|
|
53
54
|
| `checkPassed`, `checkFailed` | check results; a check that fails produces no done, so dones without a check are `dones - checkPassed` |
|
|
@@ -60,6 +61,9 @@ while the store keeps the older records.
|
|
|
60
61
|
| `usageByModel` | provider-reported total tokens per served (else requested) model |
|
|
61
62
|
| `models` | model routes and served models of the attributed requests |
|
|
62
63
|
| `writer` | the release and `live` or `backfill` |
|
|
64
|
+
| `tooling` | #248: for each peer that worked on the task (owner, reviewer, a peer with attributed turns or tokens), the add-ons from the `tooling` event of the attachment it last worked in (an attachment runs from a `state` event that brings the peer online to the next `offline`; detection may settle after the work started): `{ name, version }` from the closed list `claude-mem`, `ponytail`, `ripwire`, `open-code-review`, `codex-plugin`, `dot-admit`; version null when unknown. A peer missing here is unknown; records built from events written before #248 have no field |
|
|
65
|
+
| `briefs` | #258: task briefs handed over for the task (`delivered`) and how many carried a hub-memory fail note (`withFail`), from `memory_brief` events; absent when none was recorded |
|
|
66
|
+
| `peers` | with `tooling`: every peer with an event attributed to the task (a turn, tokens, a route), fingerprinted or not, so a peer without a fingerprint makes the task unknown for an add-on rather than off |
|
|
63
67
|
|
|
64
68
|
## Label record (`kind: "label"`)
|
|
65
69
|
|
|
@@ -80,7 +84,9 @@ person can run it (agent shells are refused), and only while research is on. The
|
|
|
80
84
|
- first-pass rate: `firstPass` over approved tasks;
|
|
81
85
|
- rework: changes requested per approved task;
|
|
82
86
|
- check-failure rate: failed checks over checks run (`checkFailed / (checkFailed + checkPassed)`);
|
|
83
|
-
- tokens and wall time per approved task, median and p90 (linear interpolation between ranks)
|
|
87
|
+
- tokens and wall time per approved task, median and p90 (linear interpolation between ranks);
|
|
88
|
+
- by memory brief (#258): the same measures for tasks whose brief carried a hub-memory fail note, a brief without one,
|
|
89
|
+
and no brief recorded (shown once any record has a brief).
|
|
84
90
|
|
|
85
91
|
They are computed each time from the records; nothing derived is stored. `ahub research export [--format jsonl|csv]
|
|
86
92
|
[--since] [--all]` writes the records for outside analysis; the CSV columns are, in order: project, task, class, pii,
|
|
@@ -89,4 +95,28 @@ checkFailed, dones, reassignments, firstPass, stuck, overlaps, conflicts, testsP
|
|
|
89
95
|
filesChanged, models, label, writerVersion, writerSource. The CSV is a flat subset; JSONL carries every field.
|
|
90
96
|
Another project's measures: `ahub --project <dir> research`.
|
|
91
97
|
|
|
98
|
+
## Add-ons (#248)
|
|
99
|
+
|
|
100
|
+
The hub writes a `tooling` event each time a peer attaches: the add-ons it works with, by name and version only, read
|
|
101
|
+
from this machine's inventory (Claude Code's root is `CLAUDE_CONFIG_DIR` when the hub's environment sets it, else
|
|
102
|
+
`~/.claude`; Codex's is `CODEX_HOME`, else `~/.codex`). Claude Code: `enabledPlugins` in its `settings.json` and the project's
|
|
103
|
+
`.claude/settings.json` and `.claude/settings.local.json` (later wins), with the version from
|
|
104
|
+
`plugins/installed_plugins.json` (a user install, or one for this project). Codex: `[plugins."<name>@..."]`
|
|
105
|
+
sections in its `config.toml` that are not `enabled = false`, and plugins whose hooks it trusts, with the version
|
|
106
|
+
from its plugin cache when there is exactly one. Every peer: `ripwire` on PATH (version unknown), and the first `dot` on PATH
|
|
107
|
+
when `dot --version` answers as the dotfiles CLI (`dot version X`, resource admission; Graphviz's `dot` does not count),
|
|
108
|
+
asked once per binary per process, without input, in the background (the hub never waits on it), and killed if it
|
|
109
|
+
has not answered within 2 s. The probe runs with a minimal environment: PATH (its absolute entries outside the project), HOME and the C locale,
|
|
110
|
+
no keys, tokens or agent markers, and a `dot`
|
|
111
|
+
inside the project is never run: opening a checkout must not execute its files, so such a `dot` does not count. Nothing else is read into the event: no plugin content, settings values, hook commands or paths. The inventory
|
|
112
|
+
is the machine's, not the session's: a session started with its own settings or plugin flags can differ.
|
|
113
|
+
|
|
114
|
+
`ahub research addons [--since 30d] [--all] [--json]` splits approved tasks per add-on: `on` when a peer that worked on
|
|
115
|
+
the task had it, `off` when every such peer's fingerprint is known and none had it, `unknown` otherwise. For success,
|
|
116
|
+
first-pass, rework and check-failure rates, tokens and wall time (medians) and collisions (overlaps plus conflicts per
|
|
117
|
+
task) it gives on, off, the difference and a 95% bootstrap interval (1000 resamples, fixed seed); below 5 tasks on
|
|
118
|
+
either side a difference is inconclusive. This is field data: the sides differ in peers, task mix and time, so it shows
|
|
119
|
+
association, not cause. Controlled arms are `ahub bench run --addon <name>=on|off` (docs/bench.md), and the decisions
|
|
120
|
+
taken from both are in `docs/addons/`.
|
|
121
|
+
|
|
92
122
|
Agents may read the measures and export (ids and counts only); `backfill` and `task label` are a person's.
|
package/docs/roles.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Role catalog (#295)
|
|
2
|
+
|
|
3
|
+
- Flow roles remain conductor, planner, implementer, verifier and reviewer. Only the existing `roles` block controls their authority and routing. Catalog roles are bounded guidance selected through `catalog_roles`; they add no tool, capability, permission mode, sandbox reach or routing preference.
|
|
4
|
+
- Default catalog assignments are absent. Existing flow contracts are byte-identical to main d83cb8dd when no catalog role is selected.
|
|
5
|
+
|
|
6
|
+
# Definitions and layers
|
|
7
|
+
|
|
8
|
+
- Shipped definitions live at `templates/roles/dev|research/<id>.md`. The first catalog has six dev and five research roles. Other shipped groups wait for the #251 measurement.
|
|
9
|
+
- Project definitions at `.agenthub/roles/<id>.md` replace the same shipped id. Machine-level definitions are deferred. Files are bounded regular files, at most 8 KiB, with no symlink/hardlink targets; project directories cannot be symlinks. Scanning is flat and capped at 64 files.
|
|
10
|
+
- A flat header declares id, name, group, summary, base, classes and source. Id equals the file stem. Base is one or more existing flow roles excluding conductor; classes name today's seven base task classes. At least one declared base must already be held by a peer receiving that session guidance.
|
|
11
|
+
- Exactly six nonempty sections, in order: Scope, Not in scope, Deliverables, Hub use, Review duties, Evidence. Rendered body is at most 2000 characters. No extra heading/personality section, code block, command-shaped line, emoji, control or non-ASCII punctuation. This syntactic lint is not an instruction-safety classifier; project text is labelled untrusted guidance and cannot change daemon authority checks.
|
|
12
|
+
- Every role has its full UTF-8 content SHA-256 and a shipped/project layer label. Invalid project files are skipped with a bounded id/reason diagnostic, never their contents. A valid shipped role remains available if an invalid override is skipped. Unknown or incompatible assignments are refused with a diagnostic and receive no catalog text.
|
|
13
|
+
|
|
14
|
+
# Selection and delivery
|
|
15
|
+
|
|
16
|
+
Example shared or machine-local config:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{ "catalog_roles": { "codex": ["backend-engineer"], "kimi": ["analyst"] } }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Blocks merge per peer as `roles` does; a local empty list clears that peer's shared list. At most two distinct ids per peer. Definitions and selections are read at daemon/MCP start in this initial slice. File edits require a new start to refresh the selected guidance.
|
|
23
|
+
- Claude channel/inbox MCP instructions append catalog guidance after flow lines. Native tools-mode MCP instructions keep flow lines only, avoiding a second copy for Codex/Kimi headless. Codex, Kimi headless, Qwen, Jcode, Pi and local receive guidance in their existing role preamble/system prompt paths.
|
|
24
|
+
- ACP/Codex deliver the bounded preamble on the first delivery of an adapter start; Pi receives its existing launch/system prompt; local keeps its existing per-call system prompt behavior. A resumed native conversation starts a new adapter publication scope; context-compaction persistence is unverified. No inference is made about whether a vendor actually consumes MCP instructions (notably Kimi TUI).
|
|
25
|
+
- `role` events record prepared ids, layers, hashes and actor `config`, never body text. Prepared means the contract was constructed, not acknowledged by a model or successfully executed. Research-record session attribution/acknowledgement remains a follow-up.
|
|
26
|
+
- Role bodies next to hub headers pass through `sanitize()`. Catalog section is bounded to two 2000-character bodies plus its metadata header. A role cannot make a native peer read-only: the peer's existing permissions still apply.
|
|
27
|
+
|
|
28
|
+
# Commands and current scope
|
|
29
|
+
|
|
30
|
+
- `ahub role list [--group <group>]` lists metadata, layers and hashes. `ahub role show <id>` displays the selected definition. Both use terminal sanitization. `ahub doctor` reports invalid definitions or assignments.
|
|
31
|
+
- Person catalog assignment/clear, settings controls and pending session marks are supported. Board cards show stored task guidance IDs without exposing role body text. Task proposal roles and review-duty notices are supported as described below. No CLI or hub tool writes a role definition.
|
|
32
|
+
- The delivered slices cover the library, bounded config/session publication, read-only diagnostics and task role guidance. Native model ingestion, compaction retention and one live role/task cycle are unverified; no study was run in the solo implementation. The parent #295 remains open for full session records, remaining surfaces and measurement criteria.
|
|
33
|
+
|
|
34
|
+
# Attribution
|
|
35
|
+
|
|
36
|
+
- Eight dev/research candidates were inspected at agency-agents f99f6aa910a442b0197b768ce0ea7751e35e2060, using their mission/rule sections as reference. Guidance is rewritten for the hub's scope and evidence contracts; persona, code samples, shell commands and autonomy claims are excluded.
|
|
37
|
+
- Each adapted role names its upstream path/commit. Research lead, analyst and fact checker are original definitions. `templates/roles/NOTICE.md` contains the upstream MIT notice; the plugin's copy is generated and freshness-checked because marketplace installation copies only the plugin directory.
|
|
38
|
+
|
|
39
|
+
# Task roles (#295)
|
|
40
|
+
|
|
41
|
+
- `hub_task_propose` accepts an optional `role` catalog id. Tasks refuses unknown ids or class mismatches before storing a row, with the allowed ids for the task base class. Research/writing aliases use their existing base class. Role ids never change routing, flow roles or permission policy.
|
|
42
|
+
- The board persists the id across restart and ownership changes. Assignment notices include bounded sanitized guidance; review requests include the role's Review duties. If this daemon prepared that native session's matching contract, the owner notice names the id without repeating its body. Externally started plugin sessions have no such receipt and retain the task guidance.
|
|
43
|
+
- PII stubs, task events and research records expose only the role id/identity, never the private task text or role body. A removed definition leaves an id-only unavailable notice.
|
|
44
|
+
- Attributed turn preparations are included in opt-in research records as described below. Board-card IDs are implemented; native role-ingestion/measurement remains unverified. No role tool accepts definition text or edits a role file.
|
|
45
|
+
|
|
46
|
+
- Complete task role guidance, header included, is capped at 2000 characters. An oversized definition is refused before proposal storage; a saved task whose definition later exceeds the cap keeps an id-only notice. Definitions are never truncated.
|
|
47
|
+
|
|
48
|
+
- Task research records retain the original proposal role identity when that event is available. Reloaded definition hashes on later task events do not replace it. A missing proposal or original hash remains unknown for live aggregation and backfill.
|
|
49
|
+
|
|
50
|
+
# Person assignment controls
|
|
51
|
+
|
|
52
|
+
- `ahub role assign <peer> <id>` adds one id to that peer's configured selection, up to two. `ahub role clear <peer> [<id>]` clears one id or all. `ahub settings set catalog_roles.<peer> inherit` restores shared/profile selection. Explicit empty lists disable catalog guidance.
|
|
53
|
+
- The Roles settings group uses the same registry, machine-local write and undo path. Known ids must match a flow base the peer holds; no role definition or flow authority is editable there. Shared config is never changed. Guidance changes apply at the next peer start.
|
|
54
|
+
- Status, console peer detail and dashboard distinguish configured guidance from a prepared active session, with pending marks. An external MCP/TUI session without a preparation receipt remains unconfirmed; configuration is not model-consumption proof. Definition file changes still require a daemon/MCP restart.
|
|
55
|
+
- `ahub task role <id> <role|none>` changes guidance through Tasks for open tasks only. It keeps ownership, class and permissions and notifies current holders with bounded guidance. Approved roles remain historical. Existing task role identity in research records is not overwritten by later changes.
|
|
56
|
+
|
|
57
|
+
# Session role research records
|
|
58
|
+
|
|
59
|
+
- Each attributed completed turn records the role ids, layers and hashes prepared in its native preamble at turn start. Opt-in research JSONL records retain these as `sessionRoles` entries with the peer and turn id; live and backfill use the same events. Role bodies are excluded, including for PII tasks.
|
|
60
|
+
- An explicit empty list means a native contract was prepared with no catalog role. `null` means no preparation receipt, as for an external plugin/TUI session. Older events without the field leave it absent; neither absence nor `null` means zero roles.
|
|
61
|
+
- A pending setting change does not rewrite a running turn. A subsequent native start prepares the new selection. These records establish preparation, not model consumption or role effectiveness. The existing CSV summary columns are unchanged; JSONL includes the full metadata.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
Board cards show the stored task guidance id, including on private task stubs,
|
|
65
|
+
without role text or extra authority. Dashboard snapshots retain separate peer
|
|
66
|
+
role metadata so current flow/catalog and pending session guidance use the same
|
|
67
|
+
source as status. Current source/native/visual verification remains pending.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Baseline reconciliation, 2026-10-13: ROLE_TEXT and roleContract source blocks
|
|
71
|
+
are byte-identical at original1cbbc57 and laterd83cb8dd; the latter changes only
|
|
72
|
+
default role construction to the peer catalog. The five original rendered
|
|
73
|
+
contracts match both fixtures. A new independent original-baseline assertion
|
|
74
|
+
retains the existingd83 assertion unchanged. Assignment-notice byte comparison
|
|
75
|
+
is separately verified by the five-peer fixture; role strings alone still do
|
|
76
|
+
not establish native consumption. Native/visual consumption and role-effect
|
|
77
|
+
measurement remain unverified.
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
The original assignment fixture uses a review task with explicit owner and
|
|
81
|
+
review.local_allowed=true so all five historical peers are valid recipients.
|
|
82
|
+
It preserves the 1cbbc57 message text/facts/acceptance instruction without catalog
|
|
83
|
+
or task guidance, using the same routing choice for both implementations.
|
|
84
|
+
This fixture passes in the actual53/0 integration group. Full final gates and
|
|
85
|
+
native consumption remain pending.
|
package/docs/sdlc.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# SDLC for agent-hub (#257)
|
|
2
|
+
|
|
3
|
+
## Authority and evidence
|
|
4
|
+
|
|
5
|
+
The issue remains the specification, Tasks remains the sole task mutation boundary, and GitHub remains authoritative for PR heads, required checks, merge commits and releases. The hub stores artifact identities and bounded structured readbacks, never issue/PR bodies. Off is the default. Advise exposes blockers without changing task transitions. Enforce blocks only the review/approval transitions listed below; it never merges, releases, edits GitHub or gives a peer additional capabilities.
|
|
6
|
+
|
|
7
|
+
A reviewed head is a full lowercase 40-character SHA observed through a successful readback, not an implementer-supplied statement. A check is evidence only for that same head. Unknown/missing required checks, unavailable GitHub, pending reviews or unresolved threads remain blockers in enforce and visible unknowns in advise. A newer head invalidates the derived review and approval readiness. Historical task approval is retained as history, not presented as approval of the new commit. Revalidate after asynchronous readbacks immediately before any board write.
|
|
8
|
+
|
|
9
|
+
## Default lifecycle
|
|
10
|
+
|
|
11
|
+
| Stage | Acting role | Artifact or exit gate | Enforcement |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| spec | person/planner | issue identity and scope | shown |
|
|
14
|
+
| plan | planner/owner | plan, branch, existing predecessor gates | existing Tasks rules |
|
|
15
|
+
| implement | owner | PR identity/current head and local check on that head | entering review, when enabled |
|
|
16
|
+
| review | assigned reviewer | current head-bound verdict, no pending change request/open thread | approval, when enabled |
|
|
17
|
+
| verify | verifier/reviewer | required checks and local gate on the reviewed head | approval, when enabled |
|
|
18
|
+
| merge | person | current-head readiness, ordered touching PRs | shown; no mutation |
|
|
19
|
+
| release | person | merged commit, version/tag, docs freshness/live receipt checklist | shown; no mutation |
|
|
20
|
+
|
|
21
|
+
The repository uses feature branches and PRs. Release PRs require merge commits because documentation stamps name release-branch ancestors. Do not describe squash as a universal release practice. Worktree/branch cleanup follows confirmed merge; installation and native readback are separate live receipts. A successful source gate cannot certify those receipts.
|
|
22
|
+
|
|
23
|
+
## Configuration and persistence contract
|
|
24
|
+
|
|
25
|
+
.agenthub/sdlc.toml contains mode off|advise|enforce and a bounded ordered stage list, using the built-in stages above by default. The loader validates built-in mappings and bounded custom stage/gate/actor definitions; custom guidance does not grant authority. Unknown stages/gates, duplicate stages, cycles, unbounded lists and unknown keys are refused with a field-level reason. A project file may define guidance/gates, but it does not expand capabilities or permissions.
|
|
26
|
+
|
|
27
|
+
Task lifecycle fields store stage, issue/PR identity, observed head, reviewed head, local-gate head/result and bounded check/readback metadata. Legacy rows read with no lifecycle metadata. Every change goes through Tasks and records its actor; adapters/tools/CLI never write Board directly. Readback timestamps identify observations, not a freshness promise. Persist no task text in lifecycle receipts; public output uses the existing PII stub and publicTitle/publicView.
|
|
28
|
+
|
|
29
|
+
A reviewer records the head it actually reviewed. If GitHub no longer reports that head, a stale verdict refuses before effects. Changes requested does not require green CI. Approval requires a current review and all configured required checks successful on that head; neutral/skipped does not substitute unless explicitly allowed by the project's gate contract. A local check records an exact SHA and its result; it is a claimed local receipt, labelled separately from externally fetched CI.
|
|
30
|
+
|
|
31
|
+
## Readbacks and presentation
|
|
32
|
+
|
|
33
|
+
Use structured gh JSON/GraphQL read-only calls with validated repository and numeric artifact identities. No shell interpolation, PR/issue body fetching, token logging or unbounded comment storage. Failure yields unknown. Required checks come from repository rules or explicitly configured names; an empty/unknown set is not silently green. Review-thread status is counted, not copied. Cancellation and task-owner generation fencing prevent a late read from approving reassigned work.
|
|
34
|
+
|
|
35
|
+
ahub sdlc status and explain expose mode, stage, gate, observed/reviewed/local-check heads, next actor and next action. Console/dashboard derive the same result. Merge ordering compares exact PR path sets, reports intersections and never guesses an automatic landing order where dependencies are unknown. Release readiness lists merged work since the tag, stale/nonancestor documentation stamps and open native/live receipts; each unknown remains visible.
|
|
36
|
+
|
|
37
|
+
## Composition and measurement
|
|
38
|
+
|
|
39
|
+
The #252 gsd-lite option remains guidance, bounded predecessor edges and criterion/evidence-ref checklists over the same board. It creates no second STATE/PLAN/HANDOFF authority and cannot auto-advance. #259 profiles supply project defaults without changing gate authority. #247 records store ids, timings and outcomes, not plan text. #251 compares off/advise/enforce and default/gsd-lite on a sealed common suite, with failures, unknowns, operator interventions and overhead retained. No experiment was run for this design.
|
|
40
|
+
|
|
41
|
+
## Delivery and verification state
|
|
42
|
+
|
|
43
|
+
The initial implementation adds built-in configuration validation, optional board receipts, fake-gh stale-head/required-check tests, Tasks transition gates and CLI/console/dashboard projections. Bounded custom stage/gate definitions and read-only merge-queue/release-source reports are implemented in the source slices below. Dependency editing/import and the actual native advise-through-merge/release cycle remain pending. The bounded checklist guidance slice below is implemented separately. A native/account cycle must be recorded separately; no merge or release is implied by this document.
|
|
44
|
+
|
|
45
|
+
## Initial commands
|
|
46
|
+
|
|
47
|
+
A per-project `.agenthub/sdlc.toml` may set `mode = "advise"` and `required_checks = ["check (ubuntu-latest)", "check (macos-latest)", "seeded guards"]`. Omit the file for off. A missing/empty check set is unknown, never a green approval gate. The built-in stage order is fixed in this slice; changing the file applies at the next hub start.
|
|
48
|
+
|
|
49
|
+
A person records ids and a claimed local receipt with `ahub sdlc record 12 '{"repo":"owner/repo","issue":109,"pr":325,"localHead":"<full SHA>","localResult":"passed","stage":"implement"}'`. Owners/reviewers have the bounded `hub_sdlc_record` tool; it accepts no remote bodies or external-check results. Only the assigned reviewer or person records a reviewed head. `ahub review 12 approved --head <full SHA>` rechecks current evidence before approval. Changes requested does not require green CI.
|
|
50
|
+
|
|
51
|
+
`ahub sdlc status` lists bounded local projections without polling every remote PR. `ahub sdlc explain 12` or `status 12` performs a fresh structured readback, with a console-only boundary and no remote body retention. Shared console/dashboard projections explicitly show unknown external evidence; they do not certify freshness from cached data. Default task rows and contracts remain unchanged when off.
|
|
52
|
+
|
|
53
|
+
# gsd-lite checklist guidance
|
|
54
|
+
|
|
55
|
+
- Select `workflow = "none" | "gsd-lite"` in `.agenthub/sdlc.toml`; none is the default and preserves existing receipts, contracts and traces. Like the SDLC mode, this file is loaded at daemon start. Workflow choice adds guidance; it does not select enforcement.
|
|
56
|
+
- A task's reviewer or the person records `phase` through `hub_sdlc_record` or `ahub sdlc record`. The board owns the receipt, with its actor/history. No writable STATE/PLAN/HANDOFF file is introduced.
|
|
57
|
+
- A phase names a bounded slug `id`, a full `head`, up to 64 existing task/predecessor records and 1..32 criterion records. `tasks` entries use `{ "id": 2, "after": [1] }`; after must match current Tasks.after edges exactly. Imports refuse missing ids, cycles, closures above 256 tasks and ordinary-parent references to private work. They do not edit dependencies, accepted owners or reservations. Create dependencies through the existing `ahub task propose --after` flow.
|
|
58
|
+
- Each criterion has a bounded `id`, boolean `required`, `result` verified|failed|unverified and up to eight hashed refs. Accepted refs are `sha256:<64-hex>`, or `artifact|check|source:<ASCII-reference>@<64-hex>`. Whole phase JSON is at most 32 KiB. The hub never fetches those refs or treats a model's claim as a deterministic check. Verified outcomes are reviewer claims, separately labelled from fresh GitHub checks.
|
|
59
|
+
- Required failed/unverified criteria, unfinished child tasks, changed/unavailable dependencies and missing/stale checklist heads make phase readiness false. In advise/off, board transitions retain their existing behavior; readiness can remain false after a historical approval. Enforce adds phase blockers only to the existing approval transition. Entering review remains possible while criteria are unverified, so the reviewer can inspect and record them.
|
|
60
|
+
- `ahub sdlc status <id>` and `explain` expose the same workflow/phase projection used by the console and dashboard; `ahub route explain` names active workflow guidance. `ahub sdlc export <id>` emits sanitized ids, states, criteria/hashes and two SHA-256 values: `stateHash` hashes that exact projection, `sourceHash` hashes the normalized effective lifecycle configuration (not a code/build attestation). Private exports contain a stub and no phase refs. Exports are read-only derived views and cannot be imported as task authority.
|
|
61
|
+
- Full GSD import, dependency editing, native acceptance and the actual advise-through-merge/release cycle remain pending. Bounded custom gates and the read-only release-source report are implemented below. No automatic advance, merge, release, permission change or experiment is included. The default versus gsd-lite #251 comparison is not run during the solo implementation.
|
|
62
|
+
|
|
63
|
+
Example reviewer receipt (task 2 already depends on task 1):
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"phase": {
|
|
68
|
+
"id": "delivery-one",
|
|
69
|
+
"head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
70
|
+
"tasks": [{ "id": 2, "after": [1] }],
|
|
71
|
+
"criteria": [{ "id": "native-smoke", "required": true, "result": "unverified", "refs": [] }]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The repeated SHA is a syntax example, not verification evidence. Replace it with the head actually reviewed. A verified criterion requires hashed evidence refs and still does not replace the configured exact-head local/CI gates.
|
|
77
|
+
|
|
78
|
+
# Custom lifecycle definition contract (#257)
|
|
79
|
+
|
|
80
|
+
- The sdlc.toml loader reads a single regular single-link file up to 64 KiB, checks its identity/size across a bounded read and refuses symlinks or changing files.
|
|
81
|
+
- Optional `definitions` in sdlc.toml maps a stage id to bounded data: `base`, `actor`, `entry_gates`, `exit_gates` and `after`. `stages` is the explicit ordered list, at most 32 distinct lower-case ASCII ids of at most 48 characters. Built-in names retain their original base; custom ids map to one of the seven existing semantic stages. Unknown keys, gates, actors, duplicate gates and references refuse before startup.
|
|
82
|
+
- The list must contain a review-base and merge-base stage because existing Tasks done/review transitions need those destinations. Other stages can be renamed, inserted or omitted. `after` has at most eight distinct earlier ids; self, forward, missing and cyclic dependencies refuse. Configuration defines no new task states, runnable commands or capability.
|
|
83
|
+
- Actors are owner, reviewer, person or planner (defaulting to the base's existing actor guidance). A configured actor never grants lifecycle write authority to a new caller. Existing task owner/reviewer/person eligibility remains the outer boundary. In enforce, an explicit custom stage change additionally requires its configured actor; a person may record every stage. A planner must already be an eligible task holder with the existing planner flow role. Off/advise preserve their nonblocking claim behavior.
|
|
84
|
+
- Gate names are issue, pr, local, review, checks and phase. A phase gate requires workflow = "gsd-lite"; otherwise configuration refuses before startup. They read only the existing artifact identities, exact-head GitHub readback, claimed local receipt or current board-owned phase checklist. Entry/exit readiness is shown separately from approval readiness. Custom gates cannot remove the existing review/approval floor, turn a missing required-check set green or treat a phase claim as external verification.
|
|
85
|
+
- Receipts keep their configured stage id. Tasks validates stage names against the active definition before storing. A definition removed after a restart makes the old stage visibly unknown until an eligible person/holder records a valid one; it is never silently remapped. Existing state-derived completion/approval selects the first configured review/merge base destination, not a hard-coded name; no arbitrary stage auto-advance is added.
|
|
86
|
+
- CLI, console and dashboard use the same definition/base/actor and entry/exit blocker projection. Every managed native/local task schema advertises the same active stage ids. Separate MCP processes read authenticated daemon status, not a mutable sdlc.toml; a live older daemon without the optional field retains the seven-stage schema. An unavailable/malformed read withholds hub_sdlc_record until a successful tools-list read rather than inventing stages. The default definition produces the old seven-stage config, receipts, schemas and projections unchanged. Native model ingestion and an actual advise/release cycle remain unverified.
|
|
87
|
+
|
|
88
|
+
Example:
|
|
89
|
+
|
|
90
|
+
```toml
|
|
91
|
+
mode = "advise"
|
|
92
|
+
required_checks = ["check (ubuntu-latest)", "check (macos-latest)", "seeded guards"]
|
|
93
|
+
stages = ["question", "draft", "fact-check", "approve", "publish"]
|
|
94
|
+
|
|
95
|
+
[definitions.question]
|
|
96
|
+
base = "plan"
|
|
97
|
+
actor = "planner"
|
|
98
|
+
entry_gates = ["issue"]
|
|
99
|
+
|
|
100
|
+
[definitions.draft]
|
|
101
|
+
base = "implement"
|
|
102
|
+
actor = "owner"
|
|
103
|
+
after = ["question"]
|
|
104
|
+
exit_gates = ["local"]
|
|
105
|
+
|
|
106
|
+
[definitions.fact-check]
|
|
107
|
+
base = "verify"
|
|
108
|
+
actor = "reviewer"
|
|
109
|
+
after = ["draft"]
|
|
110
|
+
exit_gates = ["checks"]
|
|
111
|
+
|
|
112
|
+
[definitions.approve]
|
|
113
|
+
base = "review"
|
|
114
|
+
actor = "reviewer"
|
|
115
|
+
after = ["fact-check"]
|
|
116
|
+
exit_gates = ["review"]
|
|
117
|
+
|
|
118
|
+
[definitions.publish]
|
|
119
|
+
base = "merge"
|
|
120
|
+
actor = "person"
|
|
121
|
+
after = ["approve"]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
These ids are guidance/receipt destinations. Publish neither merges nor releases. The read-only source-readiness report is implemented below. Native acceptance/release permission, bidirectional GSD import and research measurements remain unverified or pending.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# Structured documentation readiness evidence (#257)
|
|
128
|
+
|
|
129
|
+
The package-owned scripts/check-docs.mjs accepts --json with the same normal/--require-fresh verdict as its human output. Metadata includes the observed head, validated package version and sorted document identities with fresh/stale/nonancestor/unknown state, stamp, covered commit count and dirty flag when known. Invalid/error payload text is excluded from machine output; an error count and fresh=false retain uncertainty. Git readbacks disable repository-configured helpers and bound subprocess time/output. No stamp, version, tag or release is written. This evidence is a release-readiness input, not proof of prose review or native acceptance.
|
|
130
|
+
|
|
131
|
+
The release reader additionally requests --committed: manifest, README and package metadata come from the captured HEAD, and dirty documentation/evidence files block freshness. A working-tree restamp cannot certify a commit that still contains stale stamps. The ordinary checker continues to support working-tree review before those stamps are committed.
|
|
132
|
+
|
|
133
|
+
# Read-only merge queue contract (#257)
|
|
134
|
+
|
|
135
|
+
Queue reads fetch PR numbers and bounded head/check/review/thread/file-count metadata, never remote titles or bodies. Up to16 open PRs and8 external dependency reads share a20second budget. Every linked local receipt must satisfy the existing approval floor on that current head; draft/unknown status, missing file coverage and unlinked/private work remain blocked. Same-target path intersections return counts without names. Task after edges provide the only dependency order; open predecessor PRs block current readiness, unresolved touching order asks the person, cycles/truncation remain incomplete. A board approval never substitutes for a merged-commit receipt. No queue operation changes dependencies, owns work, merges or writes GitHub.
|
|
136
|
+
|
|
137
|
+
A truncated open-PR list blocks every row because omitted PRs may change the touching order. Version advancement uses SemVer precedence, including prereleases; build metadata alone is not an advance.
|
|
138
|
+
|
|
139
|
+
Missing/incomplete file evidence, an unknown target branch or a private PR also prevents conflict coverage for other rows. Their readiness stays blocked without reading the private PR.
|
|
140
|
+
|
|
141
|
+
Queue completeness requires both full file coverage and verified target branches, even when all file pages have been returned.
|
|
142
|
+
|
|
143
|
+
Touching PRs without explicit task dependency order, and their dependent PRs, appear in unordered rather than the ordered result until the person resolves them. Independent disjoint work can still be ordered. Truncated or unknown touching coverage supplies no order; a late board revision also discards the entire previously derived order.
|
|
144
|
+
|
|
145
|
+
After intervening remote PR reads, a final bounded identity-list read must match the initial open set; changes or unavailable readback invalidate readiness and order. Empty/private-only snapshots perform no intervening remote evidence reads. Repository identity matching is case-insensitive for both holders and dependencies.
|
|
146
|
+
|
|
147
|
+
Those snapshots include every PR head, which must remain unchanged and match its observed evidence. Documentation dirtiness uses staged-tree metadata, untracked names and raw blob hashing rather than git status, so clean/process filters are never invoked. Gitlinks, large files or unsupported filesystem evidence remain unverified; transformed bytes are not declared equivalent by executing a configured helper.
|
|
148
|
+
|
|
149
|
+
Snapshot target branch names and target commit identities must also stay unchanged and match the evidence used to compute file conflicts. A retarget or advancing base invalidates the report even with an unchanged PR head.
|
|
150
|
+
|
|
151
|
+
# Read-only release report contract (#257)
|
|
152
|
+
|
|
153
|
+
Report reads bind the observed local head, committed package version, published release tag and matching local/remote commit identity. Only a verified tag ancestor defines the bounded first-parent commit list. The package-owned JSON doc checker must report freshness at that same head; open/unknown native issue metadata remains a blocker. Source readiness never certifies native acceptance or permits publication, and a changed head invalidates the report. No body, issue title, task text, version bump, restamp, tag or release mutation is included.
|
|
154
|
+
|
|
155
|
+
Merged PR identities are resolved from those post-tag commits in batches of at most 100, with at most 10 associated PRs per commit and the same shared read deadline. Repository lifetime PR counts cannot truncate the report. Missing, mismatched or paginated associations remain unknown; direct commits may have no associated PR.
|
|
156
|
+
|
|
157
|
+
The predecessor is the newest non-draft entry from GitHub's descending release list, which includes prereleases. The stable-only "latest release" endpoint is not used; an RC can anchor the next RC's tag and commit coverage.
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# Delivery readback commands and surfaces (#257)
|
|
161
|
+
|
|
162
|
+
`ahub sdlc queue <owner/repository>` and `ahub sdlc release <owner/repository> [live-issue...]` issue console-only readbacks. They also run through the existing console command path. The dashboard's Delivery evidence section uses labelled inputs and read-only buttons, textContent output and existing project/instance/generation fences; switching projects discards old reports and input. The report never changes task state or grants a permission. Private document names are removed at the Tasks public projection. Ledger issue state remains metadata, never native-success proof or release permission.
|
|
163
|
+
|
|
164
|
+
The all-project manager forwards both delivery reads through the same scoped console connection with a 30-second cap, beyond their shared 20-second read budget. Stale/unknown project or instance identities and unknown operations remain refused.
|
|
165
|
+
|
|
166
|
+
After dashboard authentication, those two delivery operations get a 35-second HTTP idle limit so Bun's ordinary 10-second limit cannot cut the report early. Other actions keep the ordinary limit.
|
|
167
|
+
|
|
168
|
+
The connection idle setting is not a guaranteed 10-second deadline for an active handler. The actual HTTP fixture records that an ordinary action also completes after 11.5 seconds; that legacy behavior is retained. The owner approved correcting only the newly added test's mistaken ordinary-action failure expectation. Manager control request caps are separate from HTTP connection idle behavior. Delivery HTTP results omit the internal control-request rid.
|
|
169
|
+
|
|
170
|
+
- Runtime doc checker ships explicitly in the npm tarball and package verification asserts its presence. Merge queue phase readiness derives each holder's current board phase view under gsd-lite; absent or blocked phases remain unknown/blocked.
|