@staix/agent-hub 0.15.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/README.md +12 -8
- package/docs/agent-notes/README.md +4 -0
- package/docs/agent-notes/adapters.md +24 -8
- package/docs/agent-notes/budget.md +4 -2
- package/docs/agent-notes/daemon.md +11 -4
- package/docs/agent-notes/local-worker.md +2 -2
- package/docs/agent-notes/tasks.md +15 -3
- package/docs/agent-notes/tests.md +8 -3
- package/docs/dogfood.md +18 -6
- package/docs/events.md +1 -1
- package/docs/memory.md +78 -10
- package/docs/operations.md +160 -47
- package/docs/quickstart.md +13 -5
- package/docs/roles.md +1 -0
- package/docs/sdlc.md +11 -11
- package/docs/security.md +94 -22
- package/docs/smoke.md +58 -6
- package/docs/specs/2026-09-19-agent-hub-design.md +124 -12
- package/docs/specs/2026-09-20-upgrade-recovery-design.md +3 -1
- package/docs/verification/2026-10-24-always-ask-adapters.md +52 -0
- package/docs/verification/2026-10-24-amem-runtime.md +69 -0
- package/docs/verification/2026-10-24-codex-0164-reviewer-isolation.md +55 -0
- package/docs/verification/2026-10-24-delivery-holds-ac8.md +264 -0
- package/docs/verification/2026-10-24-hardcoded-values.md +2108 -0
- package/docs/verification/2026-10-25-0.16.0.md +82 -0
- package/docs/verification/2026-10-25-0.17.0.md +74 -0
- package/docs/verification/2026-10-25-codex-0164-reviewer-tool-call.md +52 -0
- package/docs/verification/2026-10-25-kimi-231-reviewer-compat.md +48 -0
- package/docs/verification/2026-10-25-kimi-usage-ac11.md +48 -0
- package/docs/verification/2026-10-25-qwen-dual-output-hub-e2e.md +23 -0
- package/docs/verification/2026-10-25-qwen-dual-output-t0.md +20 -0
- package/docs/verification/2026-10-25-reviewer-no-verdict-diagnostics.md +35 -0
- package/docs/verified.json +30 -18
- package/package.json +2 -2
- package/plugins/agent-hub/.claude-plugin/plugin.json +1 -1
- package/plugins/agent-hub/server.js +3421 -2176
- package/src/adapters/acp.ts +5 -2
- package/src/adapters/codex-appserver.ts +69 -1
- package/src/adapters/codex-review-isolation.ts +10 -1
- package/src/adapters/compat.ts +9 -4
- package/src/adapters/conformance/enrollment.ts +18 -4
- package/src/adapters/conformance/factories.ts +4 -1
- package/src/adapters/conformance/kit.ts +11 -0
- package/src/adapters/definitions/builtin-metadata.ts +3 -3
- package/src/adapters/definitions/native-cli-entry-qwen.ts +32 -4
- package/src/adapters/definitions/native-cli-preview-qwen.ts +9 -1
- package/src/adapters/definitions/native-factories.ts +8 -0
- package/src/adapters/definitions/native-recovery.ts +8 -0
- package/src/adapters/definitions/qwen.ts +7 -4
- package/src/adapters/local-worker.ts +5 -4
- package/src/adapters/qwen-dual.ts +578 -0
- package/src/adapters/registry-types.ts +6 -2
- package/src/adapters/registry.ts +9 -1
- package/src/adapters/reviewer-mcp.ts +12 -6
- package/src/adapters/reviewer-print.ts +100 -17
- package/src/cli/console-state.ts +20 -2
- package/src/cli/console-symbols.ts +3 -2
- package/src/cli/console-usage.ts +5 -2
- package/src/cli/console.ts +5 -1
- package/src/cli/help.ts +7 -5
- package/src/cli/identity.ts +3 -1
- package/src/cli/main.ts +44 -10
- package/src/cli/memory.ts +119 -7
- package/src/cli/output.ts +12 -4
- package/src/cli/upgrade.ts +4 -3
- package/src/hub/action-class.ts +211 -17
- package/src/hub/action-enforce.ts +13 -5
- package/src/hub/action-policy.ts +19 -8
- package/src/hub/ask.ts +16 -4
- package/src/hub/board.ts +86 -31
- package/src/hub/budget-notes.ts +65 -0
- package/src/hub/budget.ts +42 -10
- package/src/hub/bus.ts +1 -1
- package/src/hub/code-facts.ts +56 -16
- package/src/hub/conductor.ts +5 -2
- package/src/hub/config-apply.ts +7 -0
- package/src/hub/control-client.ts +1 -1
- package/src/hub/daemon.ts +384 -71
- package/src/hub/envelope.ts +1 -1
- package/src/hub/events.ts +2 -2
- package/src/hub/hub-tools.ts +3 -3
- package/src/hub/kimi-usage.ts +12 -0
- package/src/hub/lifecycle.ts +10 -5
- package/src/hub/memory-code-head.ts +44 -0
- package/src/hub/memory-code-overlay.ts +119 -0
- package/src/hub/memory-plan-guard.ts +11 -27
- package/src/hub/memory-stale-anchors.ts +159 -0
- package/src/hub/memory-symbols.ts +74 -0
- package/src/hub/planning.ts +10 -4
- package/src/hub/read-tools.ts +21 -3
- package/src/hub/sdlc.ts +34 -0
- package/src/hub/settings.ts +17 -2
- package/src/hub/settled-roles.ts +15 -3
- package/src/hub/task-sweep.ts +25 -3
- package/src/hub/tasks.ts +378 -76
- package/src/hub/token-window.ts +15 -2
- package/src/hub/window-kind.ts +13 -0
- package/src/local/tools.ts +5 -5
- package/src/memory/brief.ts +66 -16
- package/src/memory/capture.ts +26 -40
- package/src/memory/client.ts +137 -65
- package/src/memory/recall.ts +13 -22
- package/src/ui/index.html +100 -18
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tests
|
|
2
2
|
|
|
3
|
-
Scope: tests, fakes and the test gate. Read before adding or changing a test or fake under `test/` or `src/adapters/conformance/`, or editing `scripts/check.sh`, `scripts/hang-watch.sh`, `scripts/seeded-check.ts`
|
|
3
|
+
Scope: tests, fakes and the test gate. Read before adding or changing a test or fake under `test/` or `src/adapters/conformance/`, or editing `scripts/check.sh`, `scripts/hang-watch.sh`, `scripts/seeded-check.ts`, `scripts/seeds.json`, `scripts/lib/ts-ast.ts`, `scripts/changed-tests.mjs`, `scripts/check-closing-refs.mjs` or `.github/workflows/closing-refs.yml`.
|
|
4
4
|
|
|
5
5
|
- A fake's gated action that never sees its gate skips the action; never fall through to a late, unsynchronized action. Owned-group tests inject `AcpOwnedGroupPorts`; a test never signals a process group it did not spawn.
|
|
6
6
|
- When extracting production closures into a VM fixture, bind every referenced host port and actual imported policy helper. Keep native identity checks on real unstarted instances; never replace a policy predicate with an always-true stub or weaken existing assertions to accommodate a moved dependency.
|
|
@@ -16,13 +16,17 @@ Scope: tests, fakes and the test gate. Read before adding or changing a test or
|
|
|
16
16
|
- 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).
|
|
17
17
|
- A test of turn or notice behavior that is not about the snapshot budget yields an I/O turn (`await new Promise(r => setImmediate(r))`) between captures: captures in one synchronous burst share the 250 ms budget and may correctly record unknown evidence. A daemon test whose assertion needs a turn's snapshot or end evidence passes `snapshotClock: () => 0` (`DaemonOptions.snapshotClock`, #661) so a slow runner cannot spend that budget; never lengthen the budget instead. A wait on concurrent-edit evidence correlates the expected turn ids and paths (#617).
|
|
18
18
|
- 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.
|
|
19
|
-
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. After changing seeded guard logic, run its affected seeds even when search-anchor counts are unchanged. Put asynchronous calls inside `resolves`/`rejects` expectations so a mutated refusal fails a named assertion. 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. A change that moves or rewrites a line a `scripts/seeds.json` case searches for updates that case's search and replacement in the same PR (seed rot fails the gate), keeping its mutant effect and named test. Never run the full seed runner from a unit test or mutate the source checkout; inspect preserved failed fixtures before removing them. CI runs it as four sequential Linux shards (`--shard i/4`) beside the ordinary check, separately from `scripts/check.sh`; the required `seeded guards` job passes only when every shard passed, or when the decision job reused a verified identical-tree full gate (`admission == 'reuse'`). Keep that job name: branch protection and `scripts/ci-gates.mjs` read it (#457).
|
|
19
|
+
- Run `bun scripts/seeded-check.ts` before reporting the seeded-guard gate complete. After changing seeded guard logic, run its affected seeds even when search-anchor counts are unchanged. Put asynchronous calls inside `resolves`/`rejects` expectations so a mutated refusal fails a named assertion. 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. A change that moves or rewrites a line a `scripts/seeds.json` case searches for updates that case's search and replacement in the same PR (seed rot fails the gate), keeping its mutant effect and named test. Never run the full seed runner from a unit test or mutate the source checkout; inspect preserved failed fixtures before removing them. CI runs it as four sequential Linux shards (`--shard i/4`) beside the ordinary check, separately from `scripts/check.sh`; the required `seeded guards` job passes only when every shard passed, or when the decision job reused a verified identical-tree full gate (`admission == 'reuse'`). Keep that job name: branch protection and `scripts/ci-gates.mjs` read it (#457). On seed rot the checker names the anchor's symbol at a base commit and where it is now (`seedRotContext`): `--base <commit>` sets that base (CI passes the PR base from a `fetch-depth: 0` checkout; keep both), and without it the base is `merge-base origin/main HEAD`. The context is evidence only: it never relaxes the one exact match, and an unavailable base says so instead of guessing.
|
|
20
|
+
- `scripts/lib/ts-ast.ts` is the one TypeScript AST helper for scripts and source-scanning tests (`parseSource`, `callSites`, `symbolSpans`, `enclosingSymbol`, `findSymbol`; inline HTML scripts keep their offsets). It gives lexical locations only, never resolved call edges, and stays dev tooling: never import it from `src/`.
|
|
21
|
+
- The native branch ratchet (`test/daemon-native-branches.json`) is reviewed data, never regenerated by a test (rule: `adapters.md`). `test/daemon-native-proof-gates.test.ts` runs daemon code cut out of `src/hub/daemon.ts` by its text, from ` function claudePermissionLaunch(` to ` async function changePermission(` to ` async function confirmPermissionDefault(`, and the ` const isSupportedPeer =` and ` const readOnlyPeer =` bindings: renaming, reordering or reindenting them updates the test in the same PR.
|
|
20
22
|
|
|
21
23
|
- `scripts/check.sh` pins the test environment (#610): `GIT_CONFIG_GLOBAL=/dev/null`, `NO_COLOR` unset, `TERM=xterm-256color`, temp root under the OS per-user temp dir, agent markers cleared. A test that needs a person's git config or color settings sets them itself. `--changed` selects tests with `scripts/changed-tests.mjs`: changed tests (nested suites included) plus every test that names a changed file directly; docs need none; any other changed file no test names, and any gate, package or shared-fixture change, runs everything.
|
|
22
24
|
- `scripts/check.sh` holds the repo's heavy-job slot (`<git common dir>/ahub-heavy.lock`, #398) for the whole run, so a test never runs the real gate; `test/check-lock.test.ts` runs a copy in a scratch repo.
|
|
23
25
|
- The whole-suite watchdog is `AHUB_CHECK_HANG_S` (default in `scripts/check.sh`, hosted values for both OSes in `.github/workflows/check.yml`; #378, #593): raise it only when the suite was still progressing at the cutoff, never for a hung test, and keep the per-test 20 s timeout. The check job's `timeout-minutes` must leave room above that value for setup: raise them together.
|
|
24
26
|
- A seed's named test must run on Linux, where the seeded job runs: a darwin-only test reports no result there and fails the job (#382). Cover a macOS-only protection with its regression test instead.
|
|
25
27
|
|
|
28
|
+
- The `closing-refs` workflow (`.github/workflows/closing-refs.yml`, #760) runs `scripts/check-closing-refs.mjs` (PR number from argv or `PR_NUMBER`) on `opened`, `edited`, `reopened` and `synchronize`: it reads `gh pr view --json closingIssuesReferences,body,title,commits` and fails when GitHub would close an issue the title and body only mention with `Refs`, a negation or a qualifier (`Refs #15. Does not close #15.` and `Refs #15. Partially fixes #15.` fail, `Refs #15.` and `Fixes #15` pass), or when a commit message has a closing keyword, negated or not, for an issue the title and body do not mean (a squash merge carries it). An issue linked only in the sidebar passes. A keyword is meant only when nothing earlier in its sentence (ending at `.`, `!`, `?`, `;` or a line break, never a comma) matches `NEGATION`; widen that list, never narrow it to let a qualified close pass (background: README). `mentioned`, `keywordReferences`, `intentionalCloses`, `closingMisuse` and `commitMisuse` are pure and covered by `test/closing-refs.test.ts` with the real `gh` shape (`repository.name`, `repository.owner.login`); its command test puts a fake `gh` first on `PATH`, never the real one. Run it by hand with `GITHUB_REPOSITORY=<owner/repo> node scripts/check-closing-refs.mjs <number>`.
|
|
29
|
+
|
|
26
30
|
- A test of `runCheck` (`src/hub/checks.ts`, #558) injects a `CheckSpawn` (argv and options in, `{ pid, exited, signalCode, stdout, stderr }` out) and never patches `node:child_process`: the runner reads a child's exit and pipes as values through `Bun.spawn`, because node's event layer can report a quick child's exit inside `spawn()` before a listener exists under load on macOS (oven-sh/bun#45483). Keep the `ended` fixtures for the already-ended case, and do not raise the 5 s limit or the 1 s kill grace to fix a flake.
|
|
27
31
|
|
|
28
32
|
- Keep CI's Bun version sourced from `.bun-version` through the pinned setup-bun action; update the version file rather than adding per-job version literals.
|
|
@@ -31,4 +35,5 @@ Scope: tests, fakes and the test gate. Read before adding or changing a test or
|
|
|
31
35
|
|
|
32
36
|
- Keep the CI admission lock around the whole controller workflow, not just its decision job, in its per-PR (`check-pr-<number>`, `queue: single`: a newer pending run replaces the older) or main (`check-main`, `queue: max`) group, never with `cancel-in-progress: true` beside `queue: max` (GitHub refuses it) (#609); two groups admitting one tree at once is an accepted duplicate run, never a reason to fail closed on another tree. Preserve successful identical-tree full proof and required job names; a skipped job, pending controller or unavailable active inventory is never a successful full gate. In `readFullGateAdmission`, lost successful proof (404, malformed proof, a per-read timeout) only means a fresh gate runs; unknown active coverage and the global read ceilings (`GateReadLimitError`) stay unknown and refuse. CI checks out the PR head (`pull_request.head.sha`), not a merge with main: after a fix lands on main, merge main into the branch before reading CI as proof. CI reuse tests use fixed metadata fixtures and never dispatch real duplicate workflows.
|
|
33
37
|
|
|
34
|
-
- Headless-reviewer tests run `test/fakes/fake-claude-print.ts` and headless Claude implementer tests run `test/fakes/fake-claude-implementer.ts` through `command` or a PATH stand-in (the implementer with `HOME` and `CLAUDE_CONFIG_DIR` in a temp dir), and fresh Codex reviewer tests run `test/fakes/fake-codex-reviewer.ts` through `codex_bin`; a test that reaches the daemon's reviewer or implementer start must never run the real `claude` or `codex`. The fake's sandbox markers test host admission only, never native isolation. Fresh Kimi reviewer tests set and restore `KIMI_CODE_HOME` to a fixture native home (the backend links that home's `credentials/`, `oauth/` and `device_id`, else the person's `~/.kimi-code`) and run `test/fakes/fake-kimi-reviewer.ts` through `command` or a PATH stand-in, never the real `kimi`. agy tests put a fake `agy` first on PATH and set `HOME` to a temp dir before any transcript readback (`readAgyTranscript` reads `$HOME/.gemini`). Code-facts tests build `new CodeFacts({ env })` with a PATH whose first `ripwire` is a wrapper around `test/fakes/fake-ripwire.ts` (`FAKE_RIPWIRE_MODE` selects its failures), or inject Tasks' `prepareReviewBrief`; never rely on an installed ripwire, which CI does not have.
|
|
38
|
+
- Headless-reviewer tests run `test/fakes/fake-claude-print.ts` and headless Claude implementer tests run `test/fakes/fake-claude-implementer.ts` through `command` or a PATH stand-in (the implementer with `HOME` and `CLAUDE_CONFIG_DIR` in a temp dir), and fresh Codex reviewer tests run `test/fakes/fake-codex-reviewer.ts` through `codex_bin`; a test that reaches the daemon's reviewer or implementer start must never run the real `claude` or `codex`. The fake's sandbox markers test host admission only, never native isolation. Fresh Kimi reviewer tests set and restore `KIMI_CODE_HOME` to a fixture native home (the backend links that home's `credentials/`, `oauth/` and `device_id`, else the person's `~/.kimi-code`) and run `test/fakes/fake-kimi-reviewer.ts` through `command` or a PATH stand-in, never the real `kimi`. Qwen TUI tests run `test/fakes/qwen-dual.ts` (scripted by submit text) as the launched Qwen or the daemon's `qwen_cmd` (an adapter unit test also passes its own `table`), never the real `qwen`. agy tests put a fake `agy` first on PATH and set `HOME` to a temp dir before any transcript readback (`readAgyTranscript` reads `$HOME/.gemini`). Code-facts tests build `new CodeFacts({ env })` with a PATH whose first `ripwire` is a wrapper around `test/fakes/fake-ripwire.ts` (`FAKE_RIPWIRE_MODE` selects its failures), or inject Tasks' `prepareReviewBrief`; never rely on an installed ripwire, which CI does not have.
|
|
39
|
+
- Production `MemoryClient` (`src/memory/client.ts`) is the in-process amem store and never opens `memory.worker_url` (#752). A test that needs the legacy worker shape injects `FakeMemoryClient` (`test/fakes/mem-worker.ts`) as `DaemonOptions.memoryClient` or in place of the client; never add an HTTP path to the production client for a test. An amem-backed test sets its own temp `AMEM_HOME` and reads only its own fixture memory directory.
|
package/docs/dogfood.md
CHANGED
|
@@ -13,12 +13,19 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
13
13
|
| Message bus, digests, priorities | on | `ahub report`: messages, digests, overflow, undeliverable; delivery latency from events |
|
|
14
14
|
| Compact board (#724) | on | `ahub board` at 80, 120 and 200 columns: one line per task (test/board-compact.test.ts) |
|
|
15
15
|
| Backlog list table (#399) | on | `ahub backlog list` at a terminal width: one line per card by rank with the reserved owner and dependencies, and the count by owner (test/backlog-list-output.test.ts); `--json` for scripts |
|
|
16
|
+
| Native branch ratchet and fixed builtin proof gate (#625 slice 2a) | active in source/CI after merge; running daemon gate takes effect after release and upgrade | reviewed predicate/function/count/reason rows equal source; foreign native proof products and nativeRevert declarations refused; reserved ACP ports leg remains unverified until 2b |
|
|
16
17
|
| Task board, routing, roles | on (claude planner, reviewer and implementer; codex, jcode, agy implementers) | board history: lead time from propose to approve, review rounds, escalations |
|
|
17
|
-
| Planner walk and reviewer independence (#525-3) | on after the release: `ahub route explain <id>` prints the planner walk here, and with `claude` the only planner holder it names `claude` for every task (rotation among one holder); the rotation among several holders and a named planner are not exercised here,
|
|
18
|
+
| Planner walk and reviewer independence (#525-3) | on after the release: `ahub route explain <id>` prints the planner walk here, and with `claude` the only planner holder it names `claude` for every task (rotation among one holder); the rotation among several holders and a named planner are not exercised here, task bindings are tracked separately below (525-2). Reviewer independence (I-2) is on: a peer that accepted or finished a task never reviews it | the `planner: claude (rotation)` line in `ahub route explain` for a task; I-2 shown as `reviewer user` with the trace line `every eligible reviewer implemented this task: the person reviews` on a task `claude` implemented (such as #399), and as `skipped, implemented this task` on the other candidates; a former implementer that is offline or paused is refused for that reason and leaves the outcome unchanged (the trace still ends `reviewer: none, done will approve directly` where no other reviewer exists) |
|
|
19
|
+
| Per-task and release planners, I-4 (#525-2) | off until this change is released and the running hub is upgraded; this PR enables no new project planner configuration | task/release planner bindings and selection reasons; wrong-planner pre-effect refusals; independent plan-review requests and `selfReview` receipts; queued notices rerouted after a planner change; `task_planners` recovery refusals |
|
|
18
20
|
| Acceptance criteria ids in review (#507b) | on after the release: a task with a recorded `criteria` checklist lists its ids in the review request and `hub_review` unmet items that start with an id are recorded as `unmetCriteria`; tasks here rarely record a checklist, so most reviews are unchanged | the `Acceptance criteria` block in a review request and `unmetCriteria` in `ahub task show` history for tasks with a checklist; the share of changes-requested verdicts whose unmet items name an id; unmet items that name an id the checklist does not hold (a typo) |
|
|
19
21
|
| Deliverable records (#509a) | on after the release: `deliverables` on `hub_task_done` and `hub_sdlc_record`, hashed by the hub in this repository's folder; most tasks here are code with a PR and name none, so only document-shaped work (a report, a spec draft) uses it | the `Deliverables` block in a review request and `deliverables` in `ahub task show`; approvals refused with `deliverable changed since it was delivered`; records with `state: unknown` (a file the hub could not vouch for); claimed-hash refusals as a measure of agents trying to supply a hash |
|
|
22
|
+
| `ahub deliverables` and the dashboard badge (#509b) | on after the release: `ahub deliverables [--check]` on this repository's board; only tasks that named deliverables appear, so it lists document-shaped work only | the person runs `ahub deliverables --check` after a document task is approved and the next time its file is edited: a `changed since review` row names the edit; `Deliverables n` chips on cards; `not measured now` in the sheet means nobody ran `--check` since the daemon started |
|
|
20
23
|
| Roles per kind and form (#525-1, #525-3, #525-4, #525-5) | on: claude holds the implementer role in the project checkout; isolated terminal and headless Claude implementer support is on, but neither form is declared here | tasks by owner; verified owner isolation and execution-root refusals; headless task-session resumes, inbox task-session refusals, fresh notices and person approval outcomes; missing or mismatched root must never admit a write owner |
|
|
24
|
+
| Read-time memory code neighbours (#684 phase 4) | off until released; dashboard toggle is opt-in | derived call edges with current SHA; attached fail/decision brief coverage; explicit unknown/truncated results; unchanged authoritative memory log bytes |
|
|
25
|
+
| Canonical memory symbol anchors (#684 phase 3) | off until released; optional `doctor --stale-anchors` report only | actual-symbol completion anchors versus plan guesses; symbol-related earlier notes at memory hop two; stale/unknown/truncated report counts; zero note mutations during inspection |
|
|
26
|
+
| Symbol preparation and historical recall (#684 phase 3 follow-ups) | off until release | exists calls per no-reviewer completion; raw-signature fail recall; indexed-definition/unknown labels; unchanged note/candidate bytes and neutral cleanup failures |
|
|
21
27
|
| Overlap notices | on; plan symbols match by normalized name (arguments stripped, a bare name matches the last segment, two qualified names must be equal; #682 phase 1b) | `ahub report`: overlap warnings, task pairs; false-overlap rate, and symbol-only matches on bare common names (#682) |
|
|
28
|
+
| Backlog phase grooming and issue planning (#759) | off until released and the running hub supports the new planning fields; relinks for cards #138/#287 remain a post-landing planner action | related-phase duplicate count; unrelated same-issue duplicate controls; planning revisions with `fields: ["sdlc"]` or `[]`; old spec acceptance absent after relink/undo |
|
|
22
29
|
| Planner WIP caps and backlog pull (#655, #718) | on (`tasks.wip_limits.codex = 2`); reserved-pull handoff on after release | board history/offer readback: reserved `backlog pulled` -> `assigned` -> `accepted` for the same peer; stale or unowned offers, capacity refusals and held-ready entries |
|
|
23
30
|
| Task sweep (stalls, idle owners) | on | stall and sweep events per week |
|
|
24
31
|
| Turn-free coordination | off: experimental; needs a separate measured trial | coordination events, conflict notices |
|
|
@@ -39,19 +46,22 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
39
46
|
| Spec acceptance (#481 S1) | advise | build entries without acceptance |
|
|
40
47
|
| Lifecycle identity linked by the hub (#694, #723) | on in advise; links at propose and accept from the title and `refs.repo`, with a groom backfill as the safety net | open tasks still showing `issue identity missing` right after propose (should be only titles that name no issue or a qualified title without `refs.repo`) |
|
|
41
48
|
| Planner plan review (#481 S9) | advise | plans reviewed before build |
|
|
49
|
+
| Planner board-changed notice (#758) | on here, with the lifecycle in `advise`: `claude` is the planner, so a card another peer proposes or re-plans reaches it once at task weight, and its own writes, state moves, reviews and assignments cost it no turn | per planner and week: `task`-kind hub envelopes whose body starts `The board changed` (target: one per planning change, none after the planner's own write), the same envelopes at `fyi` priority (recorded, no turn: at most one per 10 minutes), and the count still queued at once (target: at most one). Read from `ahub log` and the event log; the 12 copies in 44 minutes seen on 2026-10-24 are the baseline |
|
|
42
50
|
| Plan conformance (#481 S2) | advise | PRs with files outside the plan |
|
|
43
51
|
| Test integrity for bug fixes (#481 S4) | advise | bug PRs without a red-first receipt, modified pre-existing tests |
|
|
44
52
|
| Required checks | advise (`check (ubuntu-latest)`, `check (macos-latest)`, `seeded guards`) | first-pass CI rate, same-head reruns (`hub_sdlc_costs`) |
|
|
53
|
+
| Seed anchor diagnostics (#684) | on in the seeded checker; exact-match failure remains mandatory | missing anchors report the base commit, enclosing symbol and current file/line or explicit unknown; `test/seeded-check.test.ts` |
|
|
45
54
|
| Release authorization (#481 S6) | pending (#199) | releases with a receipt |
|
|
46
55
|
| SDLC metrics and control bands (#481 S7) | `ahub sdlc metrics` on; bands off until `[bands]` is set in `.agenthub/sdlc.toml`, and they write cards only in advise or enforce (in off the report still shows tiers). Completion checks are off here, so `first_pass_check` and the PR-based figures read unknown | its own report; breach episodes per week by tier, and band cards the planner accepted rather than dropped |
|
|
47
|
-
| Fresh headless reviewers (#223, #519) |
|
|
56
|
+
| Fresh headless reviewers (#223, #519) | configured here (`codex-review`); per-tool approval correction and no-verdict diagnostics/re-offer (#783) take effect after release and upgrade | reviews by fresh sessions, findings they add; a per-review start failure names a closed cause class (#722): `ahub status` reviewer line and hub.log `[cause: ...]`, with the share of failures that are `unknown`; stale admission skips and current-policy `no_verdict` reroutes leave the reviewer available (#781); a real `hub_review` verdict per verified backend/version, beyond inventory-only proof; bounded refusal diagnostics, confirmed re-offers without queue holds, and uncertain fallback holds |
|
|
48
57
|
| Completion checks per class | off: the implementer already runs `scripts/check.sh`; a hub-run copy would double the heavy-slot use | time to verdict when on |
|
|
49
58
|
|
|
50
59
|
## Memory and knowledge
|
|
51
60
|
|
|
52
61
|
| Feature | State here | Measured by |
|
|
53
62
|
| --- | --- | --- |
|
|
54
|
-
|
|
|
63
|
+
| amem runtime integration (agent-mem#13 P4) | on after release; no claude-mem worker dependency | no-worker tripwire requests (must be 0), screened capture rows, profile refusals, all-author short-term recall, bounded-view truncation notices and curated-only ask citations |
|
|
64
|
+
| Shared memory through amem, briefs, recall preface | on; library intent briefs and plan guard (#436) take effect after release and hub upgrade; legacy index/timeline reads and worker notices retire in intent mode | notes saved per week, brief hits, fails that prevented a retry; same-input hub/library brief equality, host privacy refusals and front-of-brief plan fails despite the library byte cap or standalone screen |
|
|
55
65
|
| `ahub ask` | on | answers with cited ids |
|
|
56
66
|
| Code structure in the memory graph (#684) | pending | stale anchors, briefs with related notes |
|
|
57
67
|
|
|
@@ -62,7 +72,7 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
62
72
|
| Quota budgets and pauses | on | pauses, resets, time paused (#683) |
|
|
63
73
|
| Token usage per peer and task | `ahub report` and, from the roll-up in `hub.db`, `ahub usage [--by peer\|task\|issue\|pr\|release\|day\|model]`, `usage limits` and `usage total` (#683 U2); console tab `7` (U3) and dashboard Usage view (U4) shipped | tokens per merged PR |
|
|
64
74
|
| Context gate | off: `context.gate = 0` | context-pressure events |
|
|
65
|
-
| Always-ask action classes (#636) | on for Claude
|
|
75
|
+
| Always-ask action classes (#636) | on after release for managed Claude forms, hub-owned ACP in ask mode, local/Pi tools and received Codex command approvals; Codex native bypass stays not enforceable | classed permission requests (a `gh api graphql` query is a read, a mutation, `gh run` or `gh workflow` write and every command with a shell expansion in a classed position (`git push $B`, `rm -rf "$DIR"`) is asked about: #756, #762; `test/action-class.test.ts` holds the table), full local/Pi command visibility and denied effects for incomplete native views; actionPolicyInfo current-child enforceability, remaining class budgets and weakening attention; Codex native no-request and Kimi non-ask ceilings are explicit |
|
|
66
76
|
| Permission modes | on, person-chosen | approval prompts and their wait times |
|
|
67
77
|
| Pi and the local worker on DGX | off: DGX unreachable recently; Pi is off the roster | turns served on-prem, relay errors |
|
|
68
78
|
| PII routing | on | PII tasks and where they ran |
|
|
@@ -75,11 +85,13 @@ agent-hub is developed with agent-hub. This page lists every feature, whether it
|
|
|
75
85
|
| Dogfood scorecard (#687) | on after release; read-only weekly receipt | `ahub report --dogfood --since 7d --json`; bounded evidence and explicit unknowns |
|
|
76
86
|
| Console and dashboard | on; #719 pending-history reads and bounded native launch retries take effect after release | control-request latency, connection timeouts and launch retry notices; daemon CPU/RSS samples, measured separately from lifetime CPU |
|
|
77
87
|
| Usage view (#683) | CLI (`ahub usage`, U2), console Usage tab `7` (U3) and dashboard Usage view (U4) shipped | its own panels |
|
|
78
|
-
| Kimi usage from its wire log (#285 phase 2) | on after the release when `budget.kimi_tokens_5h` is set; this repository sets it | `tokens` and `usage` (`kimi_wire`) events per Kimi turn, the `tokens` window in `ahub budget`, and the count of `kimi usage unknown` notices; the live check against Kimi's `/usage` (AC11)
|
|
88
|
+
| Kimi usage from its wire log (#285 phase 2) | on after the release when `budget.kimi_tokens_5h` is set; this repository sets it | `tokens` and `usage` (`kimi_wire`) events per Kimi turn, the `tokens` window in `ahub budget`, and the count of `kimi usage unknown` notices; the live check against Kimi's `/usage` (AC11) stays opens |
|
|
89
|
+
| Budget window kinds and notes (#285 phase 4) | on after the release; `ahub budget`, the console peer detail, the dashboard Usage budgets row and `ahub doctor` (`kimi usage source`) run here | each window shows its kind and source, a peer without a number says why (Pi, local and Kimi included); a manual `ahub budget set` value outranks the Kimi count at the gate; the doctor row reads ok while the wire log counts |
|
|
79
90
|
| Settings reload | on | reloads applied, pending restarts |
|
|
80
91
|
| Config editing from the console and dashboard (#689) | on after release; `ahub settings edit` and console key `c` run here, the dashboard Structure group needs `ahub ui --settings`; executable keys stay console only | `config_edit` events (edits applied by tier and source), refusals shown with the loader reason, restarts left pending |
|
|
81
92
|
| Upgrade and recovery | on, per release | upgrade receipts in `docs/verification/` |
|
|
82
|
-
| Agent CLI version policy and trust (#691) | on after the release: Codex 0.163.0 verified by the [2026-10-22 receipt](verification/2026-10-22-codex-reviewer-isolation.md); Kimi 2.3.0 and Qwen 0.26.0 verified by the [model-free receipt](verification/2026-10-22-kimi-qwen-compat.md), with account/provider live legs unverified; agy 1.4.4 in-line | model-free isolation receipts, `ahub agents` verdicts, versions trusted per machine, lead time from an `agent-compat` issue to a receipt |
|
|
93
|
+
| Agent CLI version policy and trust (#691) | on after the release: Codex 0.163.0 verified by the [2026-10-22 receipt](verification/2026-10-22-codex-reviewer-isolation.md) and 0.164.0 by the [2026-10-24 receipt](verification/2026-10-24-codex-0164-reviewer-isolation.md); Kimi 2.3.0 and Qwen 0.26.0 verified by the [model-free receipt](verification/2026-10-22-kimi-qwen-compat.md), Kimi 2.3.1 by the [2026-10-25 model-free receipt](verification/2026-10-25-kimi-231-reviewer-compat.md), with account/provider live legs unverified; agy 1.4.4 in-line | model-free isolation receipts, `ahub agents` verdicts, versions trusted per machine, lead time from an `agent-compat` issue to a receipt |
|
|
94
|
+
| Qwen's own TUI over dual output (#286 Part 3) | off here: this repository's hub runs no Qwen peer (roster.qwen is off), and the limits (a hub deny ends the turn without an answer; a stalled turn is stopped only with Esc in the Qwen terminal) are for the person at that terminal to accept. Verified on Qwen 0.26.1 under an isolated HOME by the [2026-10-25 receipt](verification/2026-10-25-qwen-dual-output-t0.md); the live account leg is the person's | `test/qwen-dual.test.ts` against a fake dual-output Qwen; in real use `ahub status` stalled/detached notices per peer and the `needs_review` count of Qwen deliveries (an Esc or an exited terminal ends a turn that way; a deny completes) |
|
|
83
95
|
| Benchmarks (#251, #637) | off: `bench.enabled = false`; routing gate pending | bench receipts |
|
|
84
96
|
|
|
85
97
|
## Decisions
|
package/docs/events.md
CHANGED
|
@@ -69,7 +69,7 @@ Token usage by adapter:
|
|
|
69
69
|
opaque hash of session, agent and byte offset; no path, session id or text reaches an event. Only the four integers, the model
|
|
70
70
|
label and the time are copied from a row. The counted share is `inputOther + inputCacheCreation + output` (`kimiCountedTokens`,
|
|
71
71
|
one function): cache reads are recorded and shown, never counted against `budget.kimi_tokens_5h`. The rolling 5 h sum of the
|
|
72
|
-
counted share against that ceiling is the `tokens` window (`hub count, kimi wire log, of kimi_tokens_5h N`). Rows already in the
|
|
72
|
+
counted share against that ceiling is the `tokens` window (`hub count, kimi wire log, of kimi_tokens_5h N`, kind `count`: #285 phase 4 names each window's kind in the budget reply, never in an event, and a person's `ahub budget set` value, kind `manual`, outranks it at the gate). Rows already in the
|
|
73
73
|
session's log when the hub first sees it (a resumed session) are history and are not counted. An unreadable index, a missing,
|
|
74
74
|
shrunk or replaced file (a replacement is told by a hash of the consumed head and tail kept with each offset, since Linux can reuse the inode), a truncated last line, an unknown row shape or an untested wire `protocol_version` (only 1.5 is known)
|
|
75
75
|
makes the count unknown: one notice (`kimi usage unknown (<reason>)`), the `tokens` reading is dropped, and no figure is reported
|
package/docs/memory.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Hub memory integration
|
|
2
2
|
|
|
3
|
-
Agent-hub consumes the exact-pinned first-party [`@staix/agent-mem`](https://github.com/STAIxBWLB/agent-mem) library (current pin `0.
|
|
3
|
+
Agent-hub consumes the exact-pinned first-party [`@staix/agent-mem`](https://github.com/STAIxBWLB/agent-mem) library (current pin `0.7.0`, initial pin `0.1.1`). The package owns portable storage, tiers, graph, goals, sync, import and raw commands. Agent-hub owns caller authority, current project privacy policy, task lifecycle integration and presentation. Claude-mem is an optional, explicit import source only; runtime recall and capture make no worker HTTP requests.
|
|
4
4
|
|
|
5
5
|
## Portable core and data directory
|
|
6
6
|
|
|
7
7
|
The [agent-mem repository](https://github.com/STAIxBWLB/agent-mem) is the reference for the data model, immutable entry IDs, append-only segments, derived SQLite index and rebuild equality, home selection, import cursors, dedupe and machine sync. Shared v1 remains the default and needs no migration: schema `agent-hub.memory/v1`, canonical hashes and log/machine/lock paths remain compatible. `memoryHome()` comes from the package and selects `AMEM_HOME`, then `$AGENTHUB_HOME/memory`, then `~/.agenthub/memory`; an explicit `StoreOptions.home` keeps its parent-directory meaning. The test preload (`test/hub-home.ts`) clears inherited `AMEM_HOME` and supplies an isolated `AGENTHUB_HOME` when none is provided.
|
|
8
8
|
|
|
9
|
-
`src/memory/` contains hub integration only: briefs, recall, the
|
|
9
|
+
`src/memory/` contains hub integration only: briefs, recall, the in-process amem client and deterministic capture. `src/hub/memory-policy.ts` supplies `withoutPii`, `promotionScreen` and `mentionsPrivatePath`; `src/hub/read-tools.ts` supplies screened peer reads. Deny, hardened git, realPath and process identity come from the package's Node-safe `@staix/agent-mem/platform` entry and are re-exported through the existing local/hub/Pi modules. No core implementation is vendored in agent-hub. The `0.1.1` platform subpath is required because `0.1.0` exposes only a root entry that loads `bun:sqlite`, which Node-hosted Pi extensions cannot import. This is a packaging compatibility export; the platform algorithms are unchanged.
|
|
10
10
|
|
|
11
11
|
## Selected memory profile
|
|
12
12
|
|
|
@@ -20,7 +20,7 @@ Person-facing status and memory output show the profile and nonzero malformed-ro
|
|
|
20
20
|
|
|
21
21
|
A running daemon keeps its original binding. Explicit checks at hub operation entry and before sidecar writes fence later operations when the selector changes or becomes unavailable; they do not switch stores in place. These checks are not atomic with an in-flight core operation: changing selection during such an operation is outside the supported cutover contract. Before migration or a selector change, quiesce every consumer of this memory home and close its handles; reopen through the supported session-preserving lifecycle afterward. A public core pre-write hook is the upgrade path for atomic in-flight cutover. Current policy screening, PII-turn refusal, capture exclusion and fail-open task delivery remain in force.
|
|
22
22
|
|
|
23
|
-
Candidate/counter data stays at `M/candidates.db`, independently of the selected note profile, using the package's explicit sidecar home convention. It is not copied into `G`, migrated or synced. The hub fences sidecar producers with the note-profile binding.
|
|
23
|
+
Candidate/counter data stays at `M/candidates.db`, independently of the selected note profile, using the package's explicit sidecar home convention. It is not copied into `G`, migrated or synced. The hub fences sidecar producers with the note-profile binding. Since agent-mem 0.7.0, `amem review` lists and accepts candidates on a selected generation too, writing accepted notes into that generation; dashboard acceptance is still not added.
|
|
24
24
|
|
|
25
25
|
Source and synthetic fixture checks do not authorize migration of the person's memory home. Before real migration, every hub sharing the memory home must run 0.12.30 or later. Real rollout still needs separately approved installation, matching live package/root/profile/selector bindings, synthetic cross-write and prune readbacks, and a supported quiesce/close/reopen sequence before separately confirmed real migration. Every running hub using this home needs an authenticated receipt: a matching ready binding, or a generation-capable unbound receipt (`disabled` when native memory is off, `unavailable` when opening failed) proving it holds no memory handle. An unbound daemon and zero running hubs are quiesced for memory; a stale bound handle, unreadable registry or unknown runtime is not ready. Real account/device sync, native capture and live memory receipts remain distinct acceptance legs. See [agent-mem migration and prune](https://github.com/STAIxBWLB/agent-mem#generation-migration-and-exact-entry-prune) for the person CLI and recovery limits.
|
|
26
26
|
|
|
@@ -95,12 +95,11 @@ A running hub syncs 5 seconds after start and every `memory.sync_interval_min` m
|
|
|
95
95
|
|
|
96
96
|
- **Task briefs**: when a task is handed to an owner, its brief lists hub memory first (entries one or two hops from
|
|
97
97
|
the task's paths, symbols, issue and task: a linked fail first, then nearer, then newer; superseded entries dropped;
|
|
98
|
-
other projects' entries only when shared), then
|
|
98
|
+
other projects' entries only when shared), then related amem curated notes, `memory.brief_items` lines in all. A peer is never
|
|
99
99
|
shown the same entry twice in one hub run.
|
|
100
|
-
- **Session-start recall**: this project's long-term decisions, contracts and fails (and shared ones) lead the recall block; display-only filtering omits automatic approval notes, while changes-requested notes show their nonempty reasons. Lines preserve their headers and end at word boundaries with a visible marker when capped; each delivery deduplicates memory ids across prefaces and note lines. Stored notes and brief evidence are unchanged.
|
|
100
|
+
- **Session-start recall**: this project's long-term decisions, contracts and fails (and shared ones) lead the recall block; display-only filtering omits automatic approval notes, while changes-requested notes show their nonempty reasons. Lines preserve their headers and end at word boundaries with a visible marker when capped; each delivery deduplicates memory ids across prefaces and note lines. Stored notes and brief evidence are unchanged. Recent short-term amem curated notes follow; each gets half of `memory.inject_tokens` when both answer.
|
|
101
101
|
- **`ahub ask`**: entries that match the question and the graph neighbourhood of what they are about are evidence, cited
|
|
102
|
-
as `[mem:<8 hex>]
|
|
103
|
-
model's answer never becomes hub memory.
|
|
102
|
+
as `[mem:<8 hex>]` for existing native projections or `[mem:<32 hex>]` for full entry references. A question that carries PII skips them. `ahub ask --remember` writes a pending candidate, never curated evidence; a person must review it.
|
|
104
103
|
- **`ahub memory`** needs no running hub. The hub CLI identity gate allows screened list/search/show reads in agent shells; graph and unscreened views are a person's. Managed peers use the bounded `hub_memory_search`, `hub_memory_show` and `hub_memory_graph` tools through the daemon, with project scope, `memory_read`, PII-turn refusal and capture exclusion:
|
|
105
104
|
|
|
106
105
|
```bash
|
|
@@ -146,8 +145,8 @@ The package owns deterministic import identity, text-only graph extraction, curs
|
|
|
146
145
|
|
|
147
146
|
Whether hub memory helps is measured, not assumed (#258 AC11, with #248):
|
|
148
147
|
|
|
149
|
-
- Each task brief writes a `memory_brief` event with counts only (hub-memory items, fails among them,
|
|
150
|
-
items); research records keep `briefs` (`delivered`, `withFail`), and `ahub research` splits approved tasks into
|
|
148
|
+
- Each task brief writes a `memory_brief` event with counts only (hub-memory items, fails among them, supplemental
|
|
149
|
+
items in the legacy `claudeMem` count field; new events identify `source: "amem"`); research records keep `briefs` (`delivered`, `withFail`), and `ahub research` splits approved tasks into
|
|
151
150
|
"a fail note in its brief", "brief without a fail note" and "no brief recorded" (first pass, rework, check failures).
|
|
152
151
|
- `ahub bench run --memory off|claude-mem|native|both` declares an arm's memory and refuses a hub that runs with other
|
|
153
152
|
settings; compare the arms with `ahub bench compare`.
|
|
@@ -183,6 +182,75 @@ Agents propose a correction with `hub_memory_correct {id, text, reason}`. The ta
|
|
|
183
182
|
|
|
184
183
|
A `changes_requested` review with unmet items can create one fail candidate. Tasks screens the public task title, unmet items and review evidence before the sidecar write; private tasks, private turns, withheld text and failed or unknown screens produce no candidate. Cause and retry conditions are explicitly unknown unless a person supplies them when reviewing.
|
|
185
184
|
|
|
186
|
-
Candidates and rendered/delivered/cited counters live only in agent-mem's machine-local `M/candidates.db` (package retention: 500 candidates/project for 30 days, 10,000 counters/project for 90 days). They are never imported or synced and are not evidence for recall, briefs, ask or graph.
|
|
185
|
+
Candidates and rendered/delivered/cited counters live only in agent-mem's machine-local `M/candidates.db` (package retention: 500 candidates/project for 30 days, 10,000 counters/project for 90 days). They are never imported or synced and are not evidence for recall, briefs, ask or graph. A person reviews them with `amem review` and accepts or rejects through that CLI's TTY and policy checks, on shared v1 and, since agent-mem 0.7.0, on a selected generation. Dashboard acceptance is a later step. Accepted results are ordinary v1 notes under the package's acceptance contract; the hub tool has no acceptance authority.
|
|
187
186
|
|
|
188
187
|
Rendered observations use the final journal payload, including memory lines in prefaces and briefs, with the real delivery id. Delivered observations require the journal's first positive transport acknowledgement (or the pull path's completed read receipt). Failed or uncertain handoffs do not establish delivery; journal-less transports leave it unknown. Citation observations resolve `mem:<id8+>` in a peer message or task completion summary against screened project-visible entries. Citations use explicit `message:<envelope-id>` or `summary:<task>:<history-index>` observation keys when the source delivery is not proven; their rendered/delivered values remain unknown. They do not establish a per-delivery causal ratio. Duplicate observations are idempotent per entry/context/observation, not cumulative usage claims. Unavailable task, turn or session identity and unobserved metrics remain unknown, never zero. No observation is written for a private envelope, PII task or PII turn. These are delivery and citation proxies, not proof that an agent understood or used a note correctly.
|
|
188
|
+
|
|
189
|
+
## In-process recall and capture (agent-mem#13 P4)
|
|
190
|
+
|
|
191
|
+
The exact 0.6.0 pin is the first published package with P3. It was checked directly against the cache-busting npm registry read: gitHead `2a182f2f23b7744a746b6854f9fb920df627a99f`, published 2026-10-23. The hub uses the canonical, alias-resolved project key and the selected profile; caller-written legacy project-chain labels never select a different store. `memory.worker_url` is retained only as ignored legacy configuration, not a network destination. `ahub doctor` reports the library rather than probing a worker.
|
|
192
|
+
|
|
193
|
+
Changes from the worker integration are deliberate:
|
|
194
|
+
|
|
195
|
+
- Task briefs and ask use curated amem entries with authentic `mem:` identifiers. Raw capture is not evidence. The existing native graph-neighbourhood/fails-first path is retained.
|
|
196
|
+
- Recent recall supplements long-term notes with short-term curated notes. It does not recreate claude-mem's model-produced observation summaries. Those historical rows require the explicit person-run import.
|
|
197
|
+
- Local capture deterministically appends SessionStart, tool events, Stop excerpts and SessionEnd. Host session/turn/step/invocation identity distinguishes actual executions even when a provider reuses its tool-call id; a replay of the same observation dedupes. There is no model summarizer, worker, watcher or network call. Published CaptureStore owns bounded excerpts, cap/retention, contention spool and replay. The bound handle is reused; effective R6 config is checked before each append and a change reopens it before writing. Refusal and daemon shutdown close it.
|
|
198
|
+
- The host excludes private turns, PII tasks, private paths, memory/tool bookkeeping and secrets before capture. It screens complete input/output before truncation. Whole-row privacy screening also precedes read selection and rendering.
|
|
199
|
+
- Native task notes are written once. Auxiliary checkpoint and model-answer writes are candidates, not another curated copy; their submitted metadata is retained in the candidate text and their note kind is preserved. The complete candidate must fit the package's 4000-character limit, or the save is unavailable. Model answers are excluded from every curated read projection even if an old import contains one.
|
|
200
|
+
- Supplemental reads use bounded exact-project pages with explicit coverage; see "P4 supplemental read and capture bounds" below. Published SearchIndex supplies ranking after screening, with a term-wise labelled fallback when FTS5 is absent.
|
|
201
|
+
|
|
202
|
+
The integration test uses actual temporary stores with fetch denied and verifies recall, brief and ask without a worker, local-only capture, replay dedupe, privacy before excerpts, project binding and candidate/evidence separation. Older fixture transport tests use a host-only injected FakeMemoryClient; no URL or fixture registry is accepted from production configuration.
|
|
203
|
+
|
|
204
|
+
Historical benchmark memory-arm labels are retained for old records. Their `claude-mem`/`both` names are not evidence of a live worker on this runtime; new comparisons require a new declared condition and an amem-aware benchmark plan. No benchmark collection was run for this integration.
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
Write screening examines both the JSON representation and literal structured keys/values before storage escaping. Authoritative tool input/output JSON is decoded once, from the complete original output before excerpt bounding; arbitrary nested JSON-as-text or other encodings are not interpreted. Host locators such as cwd are not capture content and are not persisted: treating the project root as content would falsely classify every event as mentioning every private subtree. Persisted capture fields and complete tool data remain screened, and complete custom deny paths are checked before token fallback. The test-only old-HTTP projection retains its old 4000-character response cap; production capture delegates its bound to CaptureStore after policy.
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
## P4 supplemental read and capture bounds
|
|
211
|
+
|
|
212
|
+
Session-start supplemental recall is one screened short-term curated block from every author, including the receiving peer. No adapter platform whitelist or "agent-hub" pseudo-source remains. The supplemental view uses the published `readPage` keyset API: at most 16 pages of 256 exact-project candidate bodies, plus one lookahead. It never calls the materializing `list()` path. Newest project candidates are considered first; filtering private or non-short rows may leave fewer displayed rows. A remaining page produces `memory view truncated: newest 4096 project candidates considered` in recall, search and task briefs, including when all considered rows are withheld. The control status `memoryRead` reports the last read's `truncated`, `scanned` live candidate bodies and `limit`; it is not a total corpus count.
|
|
213
|
+
|
|
214
|
+
This supplemental path deliberately excludes other projects' shared rows, which could previously crowd out the project's own short-term notes. Native shared long-term recall, graph evidence and peer read tools retain their existing scope. The package still folds relation metadata during a body page; tier/scope-aware core pages and incremental metadata snapshots are the upgrade path for that remaining cost. No total-cost bound on the core refresh is claimed.
|
|
215
|
+
|
|
216
|
+
Capture reuses one store handle per bound project/profile home and closes it on a binding error and daemon shutdown. Effective published R6 config is checked before each append; changed cap or retention reopens the handle before that append, so person settings retain next-invocation behavior. Every effect still rechecks the current binding and screens complete input/output first. Persisted path metadata contains only project-relative read/write/edit paths; bash commands, git argv and outside-root paths are omitted from that column. Legacy library callers without a host invocation id still deduplicate a native id within a summary interval; live LocalPeer supplies a separate session/turn/step/invocation id. Other hosts must supply that port before claiming cross-turn identity.
|
|
217
|
+
|
|
218
|
+
## Canonical symbol anchors (#684 phase 3)
|
|
219
|
+
|
|
220
|
+
The hub normalizes function signatures with its shared symbol normalizer and uses the existing amem `symbol:<qualified>@<path>` node format. Code-backed completion anchors require explicit file identity; an unknown or name-only resolution never invents a file. Existing non-completion notes retain normalized plan-intent associations, which are not evidence that a symbol exists or changed. Completion notes replace those guesses with verified actual symbols, or none when observations are unknown.
|
|
221
|
+
|
|
222
|
+
At an admitted completion, only the current head's screened host observations are candidates. The optional code-facts `exists` check must positively confirm an unambiguous existing symbol before its node enters the new completion note. Private tasks make no symbol queries and write no memory. Unknown observations write no symbol anchors and the completion note labels their coverage unknown. At most 16 candidates are considered; new checks stop after a shared two-second scheduling budget. An already-started call retains the code-facts boundary's own bounded execution and cleanup, so this is not a strict two-second wall-clock guarantee. Missing evidence never refuses completion.
|
|
223
|
+
|
|
224
|
+
Earlier notes stay immutable. The completion note and earlier notes share the task's reset-safe node. `related(project, [symbol], limit)` reaches the earlier notes at memory hop two; literal graph edges are symbol -> completion note -> task -> earlier note. The pinned package's `graph(..., 2)` stops at the task node. No overlay, code structure, copied note, supersede operation or new storage schema is introduced.
|
|
225
|
+
|
|
226
|
+
ponytail: the symbol -> task bridge expires with the existing short-term completion finding; afterward a long-term note is found by symbol only through its own `about`. The upgrade path is phase 4 (#367), deriving edges from recorded changed symbols at read time without storing them.
|
|
227
|
+
|
|
228
|
+
Qualified-name misses from the current ripwire CLI remain unknown: version 0.6.7 can report `Parser.run` absent while observing `run` in `Parser`. Plain-name negative evidence retains its existing meaning. The shared code-facts boundary can lift this ceiling once a CLI/schema attests qualified lookup.
|
|
229
|
+
|
|
230
|
+
`ahub doctor --stale-anchors [--json]` is an optional read-only inspection of symbol anchors against the current head. It reports bounded coverage and unknown evidence explicitly. A positive absence establishes stale status; unavailable, private or ambiguous evidence does not. It never deletes, edits, promotes or repairs a note. The default doctor checks are unchanged.
|
|
231
|
+
|
|
232
|
+
Inspection considers at most 256 exact-project notes and starts at most 16 code-facts checks, with explicit unknown/truncated coverage. A task-linked anchor also requires a current, public, reset-safe task record in this repository; historical public text cannot override a now-private, foreign or missing task record. A missing/uninitialized selected profile or project shard remains unknown and is not created. Existing core reads may maintain derived indexes and reader leases, but the report changes no authoritative note or candidate record.
|
|
233
|
+
|
|
234
|
+
## Symbol preparation and historical query compatibility (#684 follow-ups)
|
|
235
|
+
|
|
236
|
+
A filled symbol-preparation key (execution root, head and merge base) is reused between the prepare-only and completion passes. Within one pass, identical name lookups share known or unknown results even when several candidate file paths use that name. Completion still rechecks current privacy, repository and head provenance; cached advice never grants authority.
|
|
237
|
+
|
|
238
|
+
Plan-guard and related-memory queries include both an explicit raw symbol input and its normalized form, so an older `symbol:foo(a: string)@x.ts` association remains reachable alongside `symbol:foo@x.ts`. This is query compatibility only; existing notes and their IDs are never rewritten.
|
|
239
|
+
|
|
240
|
+
The stale report leaves unsupported `#`, `->` and `:` lookup spellings unknown. A plain name not found by the index is labelled "absent from indexed definitions", not proof that an imported package API or type was removed. The JSON state/reason fields retain their existing meaning, with an additive label only on final validated absence rows.
|
|
241
|
+
|
|
242
|
+
Code-facts queries can register transient detached Git worktrees. Interrupted cleanup, including Ctrl-C, can leave a prunable registration. Inspection does not auto-prune: inspect `git worktree list --porcelain` and clean only a confirmed abandoned entry. A repeated owned cleanup failure returns neutral unknown coverage; borrowed handles remain caller-owned. Note and candidate bytes are unchanged by inspection.
|
|
243
|
+
|
|
244
|
+
## Read-time code neighbours (#684 phase 4)
|
|
245
|
+
|
|
246
|
+
Select a symbol in the dashboard Memory view and enable Code neighbours to inspect one hop of callers and callees. Dashed `calls` edges are computed through the optional code-facts boundary at the displayed full commit SHA; they are never stored in amem. Attached notes are highlighted, fails first. Turning the toggle off returns the stored graph. An ambiguous seed or name-only relation is withheld; unavailable or partial evidence is explicitly unknown.
|
|
247
|
+
|
|
248
|
+
`hub_memory_graph` also prepares this overlay for symbol starts. Stored and derived nodes share its existing maximum 120 nodes, 240 edges and 6144-byte serialized response budget (default 60 nodes). Omitted nodes/edges contribute to truncation. Authored note associations remain ordinary `about` or `rules_out` edges; only code calls carry the derived SHA stamp.
|
|
249
|
+
|
|
250
|
+
A preparation starts at most four canonical, path-qualified seeds and no new query after two seconds. It retains at most 32 distinct neighbours, 64 call edges and 16 screened attached notes. In-flight work retains the existing code-facts timeout and cleanup bounds. The file:name selector must attest exactly one definition; ambiguous/name-only seeds are unknown even when their relation lists are empty. Queries run outside the synchronous dashboard snapshot Git budget, and current HEAD, profile, policy and caller/task privacy are rechecked across awaits. PII tasks and turns do not query code facts.
|
|
251
|
+
|
|
252
|
+
Task briefs merge direct and neighbour-attached fail/decision notes first, deduplicate IDs and retain the existing combined `brief_items` cap and line excerpts. The cap is snapshotted once before selection; a reload applies to the next brief. The console task detail's related-note line counts this bounded brief selection, not all notes in the store; unknown code coverage remains unknown. This does not persist a code index, extend completion-note TTLs, or change amem's graph API.
|
|
253
|
+
|
|
254
|
+
Code-neighbour reads are optional work: review and completion queries take priority, interrupt an in-flight optional CLI and wait for its owned cleanup before starting. Optional unknown results are retained for five seconds; known topology is cached for thirty seconds, with a shared five-second minimum between derive starts. Current attached notes are refreshed and screened at publication, so this cache does not retain a stale note selection. Direct path/title/symbol advice is independent of code eligibility or availability and keeps its existing fail-open behaviour.
|
|
255
|
+
|
|
256
|
+
Only an open, visible Memory view requests dashboard code work. Console task detail uses a cache-only overlay lookup and returns unknown on a cold cache, without starting a code query. A derive makes one hardened Git HEAD probe; cached publication checks bounded Git-owned HEAD/ref files instead of spawning Git on every poll. Unsupported ref layouts or packed-ref inventories above 1 MiB remain unknown. Dashboard note filters apply to neighbour notes as well, and selecting a non-symbol resets the toggle. Stored symbol nodes retain their authored identity when derived edges are added.
|