727df8gbiin2jpdi44qpcbi7kk3o12nl · 496 rows
| id | issue_id | event_type | actor | old_value | new_value | comment | created_at |
|---|---|---|---|---|---|---|---|
| 019f5a77-eda7-7288-aa1a-d7bf1cffad00 | ah-xuc.12 | claimed | Eugene Blikh | {"id":"ah-xuc.12","title":"docs: sync SPEC with Stage 2 behavior","description":"SPEC.md gains normative Stage 2 sections mirroring what landed, in the established style (invariants and failure modes, not narrative): domain deltas (stalled outcome, canonical buckets as a superset of states, Run.Timeout), ports deltas (Labels, Skills, Publish), store v2 migration, vikunja labels, runner skills plus publish (never force-push), reconciler claim spec resolution + Triage bounce + parked buckets + per-run timeout + watchdog + notification ordering, httpapi webhook endpoint (HMAC, disabled when unset), config reference with the full new example, security notes (webhook secret, TG token redaction, srht push scope), roadmap section 14 marks Stage 2 delivered. Cross-check config.example.yaml for drift. AGENTS.md and CLAUDE.md only if conventions changed (mirror both if so — independent files).","acceptance_criteria":"Each new SPEC section spot-checked against the shipped code; no contradiction with Stage 1 sections; the research-v3 supersede note stays accurate","status":"open","priority":2,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-13T05:16:35Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T05:16:35Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-13T10:53:56Z |
| 019f5a86-c89e-78d5-9d45-9fa111bd917f | ah-6u0 | created | Eugene Blikh | NULL | 2026-07-13T11:10:10Z | ||
| 019f5aa0-3d65-756e-91b2-774951842177 | ah-wka | created | Eugene Blikh | NULL | 2026-07-13T11:37:58Z | ||
| 019f5aa0-82d6-775e-bb66-67329b52a4be | ah-xuc.11 | closed | Eugene Blikh | 8e29554; reviewer merge-ready with zero findings — stub honesty, hermeticity, timing discipline, full-argv equality all verified; 3-run flake probe: all six Stage 2 flows green in all runs (the one flake found is pre-existing Stage 1, filed as ah-wka) | NULL | 2026-07-13T11:38:16Z | |
| 019f5aa0-85b0-7ed4-a1ad-3695bf4f9c33 | ah-xuc.12 | closed | Eugene Blikh | e13b65c + b48849f (two wording nits); accuracy reviewer merge-ready — every behavioral claim verified against code; SPEC section-12 example validates through ahub validate-config; pre-existing RunStatus.MetaAttempt drift filed as ah-6u0 | NULL | 2026-07-13T11:38:17Z | |
| 019f5aa0-88ab-7036-9543-c212c67ea38d | ah-xuc | closed | Eugene Blikh | Stage 2 delivered: 21 commits b3ee57d..HEAD (webhook HMAC poke, Task Spec frontmatter + type-label presets + Triage bounce, parked buckets Triage/Blocked/Question, per-run timeout with store v2, stall watchdog, Telegram notifier via HTTPS_PROXY, review-branch publish to srht remotes with bounded push, e2e flows, SPEC synced to Stages 1-2). Every wave gated by hostile review + empirical validation; final epic-wide gate 11/11. Runtime prerequisites (board columns, webhook target, srht repos, TG bot) remain in ah-k23. | NULL | 2026-07-13T11:38:18Z | |
| 019f5aa7-e2b9-7290-a42a-74e32834a4cb | ah-wka | claimed | Eugene Blikh | {"id":"ah-wka","title":"runner: Status crash-inference race misclassifies a finished run (e2e flake)","description":"Found by the Stage 2 closing review (3-run e2e probe, 1 failure in 3): TestE2E (Stage 1) tasks 101/102 finalized as outcome=crashed / exit_code=-1 even though the daemon log shows the correct run-exit report received (exit_code 0/1). Root cause per static read: PiZellij.Status (internal/runner/runner.go, crash-inference fallback around lines 210-215) infers Completed/OutcomeCrashed whenever it observes neither exit.json for the attempt nor a live zellij session — a visibility window between ahub-run writing exit.json (atomic rename) and the session-liveness check observing the dying session. The e2e stub session dies immediately at child exit, making the window wide; real zellij keep-pane narrows but does not provably close it (kill-session paths, crashes). Pre-existing Stage 1 behavior, NOT introduced by the Stage 2 commits (all six Stage 2 flows were green in all three runs).\n\nDirection to evaluate: make the crash inference sticky-read-ordered — check exit.json AGAIN after observing the session dead (dead session THEN a fresh exit.json stat), or require N consecutive dead observations before inferring a crash, or have Status treat session-dead-without-exit.json as the neither-state (no evidence) for one grace tick instead of hard Completed/crashed. Any fix must keep the SPEC section 9 three-state contract and the section 10 adopt semantics intact.","acceptance_criteria":"The race window is closed or bounded (re-check ordering or grace tick); a regression test reproduces the old misclassification deterministically (stub with delayed exit.json visibility); 10 consecutive full e2e runs green","status":"open","priority":2,"issue_type":"bug","owner":"bigbes@gmail.com","created_at":"2026-07-13T08:37:59Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T08:37:59Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-13T11:46:19Z |
| 019f5aa7-e475-700b-9d01-31a057b031ee | ah-6u0 | claimed | Eugene Blikh | {"id":"ah-6u0","title":"docs: SPEC section 6 RunStatus struct omits MetaAttempt","description":"Pre-existing Stage 1 drift found during the Stage 2 SPEC sync (ah-xuc.12): the RunStatus struct listing in SPEC section 6 lacks the MetaAttempt field even though section 9 prose relies on RunStatus.MetaAttempt (the attempt recorded in .task/meta.json, 0 when absent). Make the section 6 struct field-complete to match internal/ports/ports.go.","status":"open","priority":4,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-13T08:10:10Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T08:10:10Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-13T11:46:20Z |
| 019f5acc-e475-7bbf-9862-ee91860a2752 | ah-wka | closed | Eugene Blikh | 2783d16 + 56f84bf (SPEC section 9 sync): crash inference now confirm-after-grace (re-stat + 5s window returning the neither state). Regression test falsified against old logic; 15/15 independent e2e runs green vs ~1-in-3 pre-fix; -race clean; reviewer merge-ready with the adopt corner independently confirmed unreachable | NULL | 2026-07-13T12:26:45Z | |
| 019f5acc-e76b-7c9a-bfb2-8b08a3c05f17 | ah-6u0 | closed | Eugene Blikh | 279b733: MetaAttempt added to SPEC section 6 RunStatus listing, alignment verified against gofmt; accuracy-reviewed in the follow-up gate | NULL | 2026-07-13T12:26:45Z | |
| 019f5add-4ef9-76b2-afcb-8c93b6a34284 | ah-ddd | created | Eugene Blikh | NULL | 2026-07-13T12:44:40Z | ||
| 019f5add-8608-7ca6-8e41-df42dd9c42a1 | ah-ddd | claimed | Eugene Blikh | {"id":"ah-ddd","title":"ntfy: notifier for ntfy-compatible endpoints (Prism)","description":"The operator runs Prism (phoebe-lab/prism), an ntfy-compatible notification gateway at https://prism.bigb.es/{topic} that delivers to Telegram and owns the TG proxy egress itself (patched Telego + lab singbox). Publishing to it is a plain lab-local HTTPS POST — no HTTPS_PROXY handling needed in the daemon (prism.bigb.es is inside the NO_PROXY zone). This replaces the operational need for the direct Telegram path; internal/telegram stays as an alternative.\n\nNew package internal/ntfy implementing ports.Notifier: POST the configured topic URL with Authorization: Bearer \u003ctoken\u003e, Content-Type application/json, body {\"message\": \u003ctext\u003e} (title omitted — ntfy treats it as optional; per the Prism README the JSON publish shape is {\"title\",\"message\"}). 10s client timeout, bounded response read, non-2xx = error with a short body prefix, bearer token never in logs or error strings (redact like internal/telegram does), no retries (Notify is best-effort by contract).\n\nConfig: ntfy block {url, token} — present when either is set, then both required; url must parse as http(s). Configuring BOTH ntfy and telegram is a config error (exactly one notifier; explicit over precedence). config.example.yaml gains a commented block pointing at a Prism topic URL with ${PRISM_API_KEY}.\n\ncmd/agenthubd: notifier selection becomes ntfy | telegram | slog no-op (config validation guarantees not-both); construction error fatal at startup like telegram.\n\nDocs: SPEC section 4 layout (internal/ntfy), section 6 Notifier comment, section 12 config example + validation rules, section 15 security note (bearer key via env ref, token redaction).","acceptance_criteria":"go test ./internal/ntfy/... ./internal/config/... ./cmd/... green with -race on ntfy; httptest covers success, non-2xx, token redaction, context cancellation; config table tests cover both-or-neither, bad url, both-notifiers-configured error; wiring test asserts ntfy selected when configured; full go test ./... and -tags e2e green; SPEC updated in the same style as the Stage 2 sync","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-13T09:44:41Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T09:44:41Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-13T12:44:55Z |
| 019f5afe-3104-7829-bd5b-a184b6ec55f2 | ah-ddd | closed | Eugene Blikh | 378216d+6734986+4c3c350+5438f7c + review fix (proxy wording, trimmed presence checks); reviewer merge-ready (redirect bearer-strip verified against stdlib, no token leakage); validator 11/11 incl. live wire probe matching the Prism publish shape exactly | NULL | 2026-07-13T13:20:35Z | |
| 019f7082-c1b4-7157-ae07-dec21d7cbc28 | ah-gs7 | created | Eugene Blikh | NULL | 2026-07-17T17:37:25Z | ||
| 019f7082-c4b1-717e-9fce-0f0b1ef05c92 | ah-9r4 | created | Eugene Blikh | NULL | 2026-07-17T17:37:26Z | ||
| 019f7082-c6d6-7cc9-b26b-e18925706b63 | ah-166 | created | Eugene Blikh | NULL | 2026-07-17T17:37:26Z | ||
| 019f7083-5130-7a31-9ba6-6edbe691d9f7 | ah-0ge.1 | created | Eugene Blikh | NULL | 2026-07-17T17:38:02Z | ||
| 019f7083-5495-7c7b-970f-1c7fe985f283 | ah-0ge.2 | created | Eugene Blikh | NULL | 2026-07-17T17:38:02Z | ||
| 019f7083-5885-7e92-a147-d910eb244507 | ah-0ge.3 | created | Eugene Blikh | NULL | 2026-07-17T17:38:03Z | ||
| 019f70ba-faab-75e3-8d62-c8c196b6c5b0 | ah-gs7 | updated | Eugene Blikh | {"id":"ah-gs7","title":"Ultrapack designer/validator roles via config + skills (human-scheduled)","description":"Ultrapack (github.com/bigbes/ultrapack) is an OpenCode pack, but its value is the skills (udesign/uplan/uexecute/uverify/ureview), and pi implements the Agent Skills standard — so the skills load unmodified via --skill with no porting. Stage 2 already delivers --skill materialization, task_types and per-task frontmatter roles, so multi-role work needs ZERO daemon code today: add designer/validator roles to config pointing at ultrapack skill packages under skills_dir, and let a human drag cards between them. State carries between runs in docs/tasks/\u003cslug\u003e.md on the task branch. Do this BEFORE automating the handoff (ah-0ge slice): it validates whether the roles are actually good while the orchestration is still free.\nUltrapack agents/ do NOT get ported — see the delegation-loop beads; agents become roles, not subagents.","design":"Roles are {model, prompt} today (internal/config/config.go:72). Fork ultrapack skills into skills_dir packages; rewrite @implementer/@explorer/@reviewer subagent references (uplan/SKILL.md:126-128, uexecute/SKILL.md:37, handsoff/SKILL.md:35) out of the skill bodies — pi has no @-mention dispatch. Designer role MUST use ultrapack's handsoff skill: udesign/SKILL.md says 'Nothing is planned or written until the user approves', which deadlocks a board-driven run until the watchdog kills it as stalled.","acceptance_criteria":"A task labeled for the designer role produces a docs/tasks/\u003cslug\u003e.md with a Design section and lands In Review without stalling; dragging it to Ready under the validator role produces a review against that same file on the same branch.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:25Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:37:25Z"} | {"notes":"VERIFIED 2026-07-17 on pi 0.73.1: ultrapack skills load unmodified via --skill. Clean test (neutral empty cwd, tools on): --no-skills alone -\u003e catalog NONE; --no-skills --skill skills/udesign --skill skills/uplan -\u003e catalog is EXACTLY {udesign, uplan}. Determinism property (SPEC §9: explicit --skill under --no-skills = intended set only) holds in practice. Probe gotchas for reruns: (1) run from a dir with no skills/ folder or the model just ls-es it and reports dir names; (2) do NOT use --no-tools — pi exposes skills THROUGH a tool, so --no-tools hides even loaded skills."} | NULL | 2026-07-17T18:38:49Z |
| 019f70ba-fcfe-79cf-89e7-dde68993b3b5 | ah-166 | updated | Eugene Blikh | {"id":"ah-166","title":"pi version drift: SPEC pins 0.70.2, installed is 0.73.1","description":"SPEC §9 says 'Verified against zellij 0.44.3 and pi 0.70.2' and internal/runner/commands.go repeats the pin in its header comment, but the installed pi is 0.73.1 (@mariozechner/pi-coding-agent). Nothing is known to be broken — but every argv note in commands.go ('pi 0.70.2 still loads a path given as --skill even under --no-skills', 'There is no --name flag') is an empirical claim against a version that is no longer the one running. Re-verify the flag behaviours on 0.73.1 and update the pins, or pin the installed version deliberately.","status":"open","priority":3,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:27Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:37:27Z"} | {"notes":"Partial data point 2026-07-17: on installed pi 0.73.1, --skill paths STILL load under --no-skills (verified via catalog probe), so that SPEC §9 argv note survives the 0.70.2-\u003e0.73.1 bump. Full flag re-verification (--no-extensions with explicit -e, --mode json event shape, --name absence) still pending."} | NULL | 2026-07-17T18:38:50Z |
| 019f70c3-af18-7dfa-bb2d-1b3c51f1612e | ah-166 | closed | Eugene Blikh | Re-verified on pi 0.73.1: no runner-relevant drift. --skill loads under --no-skills; --mode json session-id line and message_end usage.cost.total shape unchanged (confirmed with opencode/claude-haiku-4-5; deepseek reports empty usage as a provider quirk, and the user-echo message_end always had empty usage); no --name flag; -ne keeps explicit -e. Pins annotated in commands.go:8 and SPEC §369. zellij NOT re-checked. | NULL | 2026-07-17T18:48:20Z | |
| 019f70c4-9923-7a25-898a-b4ee62bb18b8 | ah-9r4 | updated | Eugene Blikh | {"id":"ah-9r4","title":"DECISION: worktree/branch topology for agent-created child tasks","description":"Blocks the delegation loop. Parent X owns worktree \u003cwork_root\u003e/\u003cslug\u003e/task-X on branch agent/task-X. Where does child Y work? git refuses to check the same branch out into two worktrees, so Y cannot enter X's. Branching Y off the default branch means a later merge into X's divergent branch; branching Y off agent/task-X breaks the review/publish path, because gitLogOneline/gitDiffStat (internal/runner/commands.go) compute \u003cdefault\u003e..HEAD against the repo default branch and would report all of X's work as Y's diff.\nProposed split by whether the role writes code: ADVISORY roles (research/review/design — return text, touch no code) get a detached-HEAD worktree at X's tip. git permits many worktrees on the same COMMIT, just not the same BRANCH, so Y reads X's WIP with no collision and no merge. Only WRITER roles need real branches and a merge story — and the advisory-only subset may cover the useful cases, deferring the writer problem entirely.\nVerify the detached-HEAD claim against the pinned git before building on it.","acceptance_criteria":"A written decision recording: which roles are advisory vs writer, how each child's worktree base is chosen, and what the diffstat base is for a child (if writer roles are in scope at all).","status":"open","priority":2,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:26Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:37:26Z"} | {"design":"DECISION (verified on git 2.55.0, 2026-07-17):\n\nSPLIT roles by whether they write code.\n\nADVISORY roles (research/review/design — read parent WIP, return TEXT, publish nothing): each child gets a DETACHED-HEAD worktree at the parent's tip commit:\n git worktree add --detach \u003cchild-wt\u003e \u003cparent-tip-sha\u003e\nProven: child sees parent's uncommitted-into-branch WIP (the parent's committed tip), runs on 'HEAD (no branch)', and any commits it makes do NOT move the parent's agent/task-\u003cid\u003e branch. Teardown (git worktree remove) leaves only unreferenced commits — no branch leak, no merge. This is the recommended FIRST and possibly ONLY implementation.\n\nWRITER roles (produce code that must land on the parent's branch): DEFERRED. They need a real branch plus a merge story, and note that gitDiffStat/gitLogOneline compute \u003cdefault\u003e..HEAD — a writer child branched off agent/task-\u003cid\u003e would misattribute ALL of the parent's work as the child's diff, so a writer child needs a different diff base (merge-base against the parent branch, not the repo default). Do not build until an advisory-only loop proves insufficient.\n\nConfirmed anti-pattern: git refuses 'worktree add \u003cpath\u003e agent/task-X' while X's worktree holds that branch ('already used by worktree at ...'), so a child can never simply enter the parent's branch.\n\nCODE SEAM for ah-0ge.1: the runner's worktree creation (internal/runner/commands.go gitWorktreeAddNewBranch, base=default) needs a base-override path for child tasks: detached add at the parent tip instead of a new branch off default. Child worktree path can follow the normal \u003cwork_root\u003e/\u003cslug\u003e/task-\u003cchildid\u003e convention; only the base differs."} | NULL | 2026-07-17T18:49:20Z |
| 019f70c4-9afa-7a16-a35e-03cab283f63a | ah-9r4 | closed | Eugene Blikh | Decided: advisory children use detached-HEAD worktree at parent tip (verified git 2.55.0); writer children deferred. Full rationale + code seam in the design field. | NULL | 2026-07-17T18:49:20Z | |
| 019f70c7-3b74-73d8-ba87-59448902fd8e | ah-gs7 | updated | Eugene Blikh | {"id":"ah-gs7","title":"Ultrapack designer/validator roles via config + skills (human-scheduled)","description":"Ultrapack (github.com/bigbes/ultrapack) is an OpenCode pack, but its value is the skills (udesign/uplan/uexecute/uverify/ureview), and pi implements the Agent Skills standard — so the skills load unmodified via --skill with no porting. Stage 2 already delivers --skill materialization, task_types and per-task frontmatter roles, so multi-role work needs ZERO daemon code today: add designer/validator roles to config pointing at ultrapack skill packages under skills_dir, and let a human drag cards between them. State carries between runs in docs/tasks/\u003cslug\u003e.md on the task branch. Do this BEFORE automating the handoff (ah-0ge slice): it validates whether the roles are actually good while the orchestration is still free.\nUltrapack agents/ do NOT get ported — see the delegation-loop beads; agents become roles, not subagents.","design":"Roles are {model, prompt} today (internal/config/config.go:72). Fork ultrapack skills into skills_dir packages; rewrite @implementer/@explorer/@reviewer subagent references (uplan/SKILL.md:126-128, uexecute/SKILL.md:37, handsoff/SKILL.md:35) out of the skill bodies — pi has no @-mention dispatch. Designer role MUST use ultrapack's handsoff skill: udesign/SKILL.md says 'Nothing is planned or written until the user approves', which deadlocks a board-driven run until the watchdog kills it as stalled.","acceptance_criteria":"A task labeled for the designer role produces a docs/tasks/\u003cslug\u003e.md with a Design section and lands In Review without stalling; dragging it to Ready under the validator role produces a review against that same file on the same branch.","notes":"VERIFIED 2026-07-17 on pi 0.73.1: ultrapack skills load unmodified via --skill. Clean test (neutral empty cwd, tools on): --no-skills alone -\u003e catalog NONE; --no-skills --skill skills/udesign --skill skills/uplan -\u003e catalog is EXACTLY {udesign, uplan}. Determinism property (SPEC §9: explicit --skill under --no-skills = intended set only) holds in practice. Probe gotchas for reruns: (1) run from a dir with no skills/ folder or the model just ls-es it and reports dir names; (2) do NOT use --no-tools — pi exposes skills THROUGH a tool, so --no-tools hides even loaded skills.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:25Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T15:38:50Z"} | {"notes":"HEADLESS BEHAVIOR VERIFIED 2026-07-17 (opencode/claude-haiku-4-5, pi -p --mode json, udesign loaded via --skill on a throwaway repo): the designer run did NOT deadlock. 9 turns, read/bash/write tools, stopReason=stop, and it WROTE docs/tasks/mul-div.md following udesign's structure (Invariants/Principles/Assumptions/Unknowns + TDD decision).\n\nCRITICAL REQUIREMENT for the designer role prompt: this only worked because the rendered PROMPT explicitly neutralized udesign's collaborative-approval framing — 'No human is available; you will not receive a reply; make reasonable assumptions and record them; do not end by asking a question; WRITE the result to \u003cpath\u003e'. A naive 'design X' prompt would likely trigger the skill's 'nothing until the user approves' path and land In Review with only a question and no artifact. So prompts/designer.md MUST carry the autonomy+write-artifact framing (a lighter alternative to loading the full handsoff skill; both work). Same pattern will apply to validator/ureview.\n\nAside: openai-codex provider on this box is a ChatGPT account and rejects some models (gpt-5.2 -\u003e 400 invalid_request). Use opencode/* or deepseek/* for local pi tests; daemon uses litellm anyway."} | NULL | 2026-07-17T18:52:12Z |
| 019f70cd-36bd-7e63-9b16-e8df7643b106 | ah-0ge.1 | claimed | Eugene Blikh | {"id":"ah-0ge.1","title":"Agent-created tasks via .task/tasks.json file channel","description":"First slice of the delegation loop: agent X declares the child roles it needs, X exits, the reconciler creates those tasks. Deliberately NOT the full ah-0ge tools API — no bearer tokens, no ahub tool CLI, no HTTP endpoints. X writes .task/tasks.json on the way out; the reconciler reads it at run end, the same way .task/question.json is already reserved (SPEC:392) in a directory internal/runner/taskfiles.go already owns.\nA file channel can only be read at run END, which would cripple an interactive ask-user loop but is EXACTLY the semantics wanted here ('agent X stops'). That constraint is what makes this slice small.\nServer-side policy from the ah-0ge epic still applies: gen\u003c=2, per-session caps, dedup, project allowlist. A child that spawns children that spawn children fills the board.","design":"Child tasks get a role (must exist in cfg.Roles) + a task body. Open: do children land in Ready directly (agent-\u003eagent, per the proposal) or in Triage for a human to release (per SPEC §14.4 as written)? Triage is the safer default and can be relaxed later via config.","acceptance_criteria":"A run whose agent writes .task/tasks.json with two child role tasks results in two new board tasks with those roles; a malformed or over-cap file bounces the parent rather than creating anything.","status":"open","priority":3,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:02Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:38:02Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-17T18:58:44Z |
| 019f70dd-4b62-71e8-9068-8281280426bc | ah-0ge.1 | updated | Eugene Blikh | {"id":"ah-0ge.1","title":"Agent-created tasks via .task/tasks.json file channel","description":"First slice of the delegation loop: agent X declares the child roles it needs, X exits, the reconciler creates those tasks. Deliberately NOT the full ah-0ge tools API — no bearer tokens, no ahub tool CLI, no HTTP endpoints. X writes .task/tasks.json on the way out; the reconciler reads it at run end, the same way .task/question.json is already reserved (SPEC:392) in a directory internal/runner/taskfiles.go already owns.\nA file channel can only be read at run END, which would cripple an interactive ask-user loop but is EXACTLY the semantics wanted here ('agent X stops'). That constraint is what makes this slice small.\nServer-side policy from the ah-0ge epic still applies: gen\u003c=2, per-session caps, dedup, project allowlist. A child that spawns children that spawn children fills the board.","design":"Child tasks get a role (must exist in cfg.Roles) + a task body. Open: do children land in Ready directly (agent-\u003eagent, per the proposal) or in Triage for a human to release (per SPEC §14.4 as written)? Triage is the safer default and can be relaxed later via config.","acceptance_criteria":"A run whose agent writes .task/tasks.json with two child role tasks results in two new board tasks with those roles; a malformed or over-cap file bounces the parent rather than creating anything.","status":"in_progress","priority":3,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:02Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T15:58:45Z","started_at":"2026-07-17T15:58:45Z"} | {"notes":"IMPLEMENTED 2026-07-17. Agent writes .task/tasks.json ({tasks:[{role,title,body}]}); a SUCCESSFUL run's finalize reads it and creates one board card per entry under its role (frontmatter 'role: X') in the configured target bucket.\n\nDecisions made during implementation:\n- Ready vs Triage: config knob agent_tasks.target_bucket, DEFAULT 'triage' (spec §14.4-aligned, safe: human vets agent-created work). Flip to 'ready' for the full auto agent→agent loop. Documented in config.example.yaml + SPEC §12.\n- 'Bounce' semantics: malformed/over-cap/unknown-role/empty-title creates NOTHING (atomic) and posts a rejection comment on the parent; the parent's OWN work still finalizes to In Review. Chose comment-not-card-move because moving the parent to Triage collides with the state model (triage is a parked bucket, not a task State, and the parent has a persisted record). Stronger card-move bounce deferred.\n- gen\u003c=2 cap DEFERRED to ah-0ge.2: needs task lineage (parent link) which doesn't exist yet. Only the per-run COUNT cap (max_per_run, default 5) is enforced now.\n- Mid-creation transport failure keeps already-created children (can't un-create) and stops; logged. finalize isn't retried post-InReview.\n\nNew surface: domain.RequestedTask; ports.Board.CreateTask + ports.NewTask; ports.Runner.RequestedTasks; runner.readTasksFile + PiZellij.RequestedTasks; vikunja.Client.CreateTask (PUT /projects/{id}/tasks then MoveToBucket); reconcile.spawnChildTasks/validateRequestedTasks/childDescription; config.AgentTasks. Tests: reconcile (spawn 2, unknown-role bounce, over-cap bounce, malformed bounce), runner (readTasksFile absent/valid/malformed), vikunja (CreateTask HTTP path), config (defaults + 2 validation failures). Full suite + e2e green under GOFLAGS=-mod=readonly."} | NULL | 2026-07-17T19:16:18Z |
| 019f70dd-4db9-79d7-bbb7-438bcc944910 | ah-0ge.1 | closed | Eugene Blikh | Implemented and tested: agent-created child tasks via .task/tasks.json file channel. Acceptance met (two children created; malformed/over-cap bounces atomically). Config knob defaults to Triage; gen-cap deferred to ah-0ge.2. | NULL | 2026-07-17T19:16:19Z | |
| 019f712f-0ce2-79eb-b2de-26915f09aef8 | ah-0ge.2 | claimed | Eugene Blikh | {"id":"ah-0ge.2","title":"Parent auto-Block/unblock join on child completion","description":"The join half of the delegation loop, per SPEC §14.4 'parent auto-Block/unblock'. When X spawns children it parks in the Blocked bucket — which already exists as a parked bucket that never claims and never kills (SPEC:174) — and returns to Ready when all children reach a terminal state. Needs a parent link (tasks.parent_id in internal/store/schema.sql, or Vikunja task relations) plus somewhere to hold each child's result for the resume payload.\nUNSPECIFIED IN THE SPEC AND NEEDS A DECISION: partial failure. Y done, Z failed — does X resume with the failure reported, bounce to Failed, or go to Triage? §14 says auto-unblock but not what unblock means when a child died.","acceptance_criteria":"X with children Y,Z sits in Blocked while either runs and returns to Ready only once both are terminal; the partial-failure path is decided and covered by a transitions test.","status":"open","priority":3,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:03Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:38:03Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-17T20:45:36Z |
| 019f7138-1076-7d84-9b11-fdb4d8a0cf24 | ah-0ge.2 | updated | Eugene Blikh | {"id":"ah-0ge.2","title":"Parent auto-Block/unblock join on child completion","description":"The join half of the delegation loop, per SPEC §14.4 'parent auto-Block/unblock'. When X spawns children it parks in the Blocked bucket — which already exists as a parked bucket that never claims and never kills (SPEC:174) — and returns to Ready when all children reach a terminal state. Needs a parent link (tasks.parent_id in internal/store/schema.sql, or Vikunja task relations) plus somewhere to hold each child's result for the resume payload.\nUNSPECIFIED IN THE SPEC AND NEEDS A DECISION: partial failure. Y done, Z failed — does X resume with the failure reported, bounce to Failed, or go to Triage? §14 says auto-unblock but not what unblock means when a child died.","acceptance_criteria":"X with children Y,Z sits in Blocked while either runs and returns to Ready only once both are terminal; the partial-failure path is decided and covered by a transitions test.","status":"in_progress","priority":3,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:03Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T17:45:37Z","started_at":"2026-07-17T17:45:37Z"} | {"notes":"PARTIAL 2026-07-17. Split delivered: the parent↔child LINEAGE + DEPTH CAP is done and tested; the behavioral block/wait/resume JOIN is deferred and coupled to ah-0ge.3 (see finding below).\n\nDELIVERED (green, GOFLAGS=-mod=readonly):\n- store schema v3: task_parents(child_id PK, parent_id, generation, created_at) + migration [2]-\u003e[3].\n- ports.Store + store: RecordChild, GenerationOf, ChildIDsOf (idempotent on child_id).\n- config.AgentTasks.MaxGeneration (default 2, must be positive).\n- reconcile.spawnChildTasks now enforces the depth cap (a task at generation \u003e= MaxGeneration cannot delegate; childGen = parentGen+1) and records each child's lineage on creation; 'spawned_tasks' event carries generation.\n- Tests: store lineage round-trip + idempotency; reconcile lineage-recorded + over-depth rejection; config default + negative-generation validation; migration tests updated to schemaVersion + task_parents presence.\n\nARCHITECTURAL FINDING (blocks the join; needs a decision):\nah-0ge.2 and ah-0ge.3 are INSEPARABLE. If a blocked parent 'unblocks' into a plain re-claim without its pi session context, it re-runs from scratch, re-spawns the same children, and blocks again — infinite re-delegation (bounded only by caps). So 'unblock' is only correct AS 'resume-with-context', which is ah-0ge.3. Also, a delegating parent must WAIT in a real state: 'blocked' is currently a parked BUCKET, not a task State, so the join requires promoting blocked to a normative State (domain.States/Valid/CanClaim/transitions + the reconcile bucket switch) — SPEC §14.4 explicitly sanctions this ('blocked earns real semantics in Stage 4').\n\nDECISIONS captured for the join (from the user): child counts as done at IN REVIEW (not Done); partial failure -\u003e resume the parent reporting each child's outcome, parent may retry a couple of times (bounded by MaxGeneration + a future per-parent round cap).\n\nRECOMMENDATION: implement the join + resume as ONE unit (merge ah-0ge.2 remaining scope with ah-0ge.3), starting by promoting 'blocked' to a real State."} | NULL | 2026-07-17T20:55:27Z |
| 019f7138-3740-71ec-b759-20a6fadd8286 | ah-0ge.3 | updated | Eugene Blikh | {"id":"ah-0ge.3","title":"Resume parent via pi --session with child results as a new attempt","description":"Closes the loop: X comes back from Blocked and continues WITH its original context rather than starting cold. runs.pi_session_id is already a column in internal/store/schema.sql and pi supports --session \u003cpath|id\u003e (0.73.1, also --session-dir), so this is mostly plumbing — but two things need care.\n(1) Session survival: X's pi session must outlive the park. Pin --session-dir explicitly rather than relying on a default location, and confirm X's worktree is not reclaimed while parked.\n(2) Result transfer contract: Y's output has to serialize out of Y's run, through the board, and into X's resume prompt. Needs a defined shape and a size bound — in-process subagents return text into the parent's context for free, this path does not.","design":"Resume is a NEW attempt on X (runs table already keys on (task_id, attempt)), so watchdog/cost/event plumbing is unchanged. Prompt gets an extra rendered section carrying each child's role + result.","acceptance_criteria":"X resumes after its children finish, its pi session id is unchanged across the park, the new attempt shows the children's results in the rendered prompt, and an oversized child result is truncated rather than breaking the resume.","status":"open","priority":3,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:04Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T14:38:04Z"} | {"notes":"COUPLING (2026-07-17): inseparable from ah-0ge.2's behavioral join — see ah-0ge.2 notes. 'Unblock' is only correct as this resume-with-context, else the parent re-runs from scratch and re-spawns children (infinite re-delegation). Recommend implementing ah-0ge.2 (remaining join) + ah-0ge.3 as one unit, starting by promoting 'blocked' to a real domain.State. Lineage foundation (task_parents, ChildIDsOf) already landed under ah-0ge.2."} | NULL | 2026-07-17T20:55:37Z |
| 019f7177-caa8-7d75-bf84-df653d118195 | ah-0ge.2 | updated | Eugene Blikh | {"id":"ah-0ge.2","title":"Parent auto-Block/unblock join on child completion","description":"The join half of the delegation loop, per SPEC §14.4 'parent auto-Block/unblock'. When X spawns children it parks in the Blocked bucket — which already exists as a parked bucket that never claims and never kills (SPEC:174) — and returns to Ready when all children reach a terminal state. Needs a parent link (tasks.parent_id in internal/store/schema.sql, or Vikunja task relations) plus somewhere to hold each child's result for the resume payload.\nUNSPECIFIED IN THE SPEC AND NEEDS A DECISION: partial failure. Y done, Z failed — does X resume with the failure reported, bounce to Failed, or go to Triage? §14 says auto-unblock but not what unblock means when a child died.","acceptance_criteria":"X with children Y,Z sits in Blocked while either runs and returns to Ready only once both are terminal; the partial-failure path is decided and covered by a transitions test.","notes":"PARTIAL 2026-07-17. Split delivered: the parent↔child LINEAGE + DEPTH CAP is done and tested; the behavioral block/wait/resume JOIN is deferred and coupled to ah-0ge.3 (see finding below).\n\nDELIVERED (green, GOFLAGS=-mod=readonly):\n- store schema v3: task_parents(child_id PK, parent_id, generation, created_at) + migration [2]-\u003e[3].\n- ports.Store + store: RecordChild, GenerationOf, ChildIDsOf (idempotent on child_id).\n- config.AgentTasks.MaxGeneration (default 2, must be positive).\n- reconcile.spawnChildTasks now enforces the depth cap (a task at generation \u003e= MaxGeneration cannot delegate; childGen = parentGen+1) and records each child's lineage on creation; 'spawned_tasks' event carries generation.\n- Tests: store lineage round-trip + idempotency; reconcile lineage-recorded + over-depth rejection; config default + negative-generation validation; migration tests updated to schemaVersion + task_parents presence.\n\nARCHITECTURAL FINDING (blocks the join; needs a decision):\nah-0ge.2 and ah-0ge.3 are INSEPARABLE. If a blocked parent 'unblocks' into a plain re-claim without its pi session context, it re-runs from scratch, re-spawns the same children, and blocks again — infinite re-delegation (bounded only by caps). So 'unblock' is only correct AS 'resume-with-context', which is ah-0ge.3. Also, a delegating parent must WAIT in a real state: 'blocked' is currently a parked BUCKET, not a task State, so the join requires promoting blocked to a normative State (domain.States/Valid/CanClaim/transitions + the reconcile bucket switch) — SPEC §14.4 explicitly sanctions this ('blocked earns real semantics in Stage 4').\n\nDECISIONS captured for the join (from the user): child counts as done at IN REVIEW (not Done); partial failure -\u003e resume the parent reporting each child's outcome, parent may retry a couple of times (bounded by MaxGeneration + a future per-parent round cap).\n\nRECOMMENDATION: implement the join + resume as ONE unit (merge ah-0ge.2 remaining scope with ah-0ge.3), starting by promoting 'blocked' to a real State.","status":"in_progress","priority":3,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:38:03Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T17:55:27Z","started_at":"2026-07-17T17:45:37Z"} | {"notes":"COMPLETED 2026-07-17 together with ah-0ge.3 (they were inseparable — see prior note). The full block→wait→resume join is implemented and tested.\n\nSTATE MODEL: 'blocked' promoted to a real domain.State (7 states now). domain.States/Valid/CanClaim/CanonicalBuckets updated; BucketBlocked const removed (blocked is a state, not a parked bucket); triage/question remain parked. reconcile iterate() routes the blocked bucket to a new handleBlocked.\n\nBEHAVIOR: a successful run that validly delegates now PARKS the parent in Blocked (delegateAndBlock) instead of In Review; children are created in target_bucket (triage=human-gated, ready=full-auto). handleBlocked resumes the parent (new attempt, resumeParent) once EVERY child reaches a terminal bucket (in_review/failed/done/cancelled; a vanished child counts terminal to avoid deadlock). Resume re-runs the role prompt + an appended 'Delegated work completed' section reporting each child's outcome and instructing 'do not re-delegate'. Child-done threshold = In Review (decision). Partial failure = resume-and-report; agent may retry (decision), bounded by MaxPerRun as a per-parent LIFETIME cap (existing ChildIDsOf count + requested) so retries can't loop forever. Depth bounded by MaxGeneration.\n\nTests: domain (7 states); reconcile (spawn→blocks, resume-when-children-finish incl. failed child in prompt, waits-while-pending, + updated ah-0ge.1 spawn/reject tests); store migration/lineage. Full unit suite + e2e green under -mod=readonly. SPEC §9-pseudocode, state model, and §12 updated.\n\nNOTE/deviation: resume is a fresh attempt in the parent's existing worktree (which holds its committed work) + resume prompt, NOT a literal 'pi --session' continuation — pi session-file mechanics weren't verifiable here, and the worktree+prompt path is robust and correctness-equivalent for avoiding re-delegation. True --session continuation is a possible future optimization (see ah-0ge.3)."} | NULL | 2026-07-17T22:05:03Z |
| 019f7177-ce38-7e4c-9efc-a9431043c0ae | ah-0ge.2 | closed | Eugene Blikh | Block→wait→resume join implemented and tested together: blocked promoted to a real state; delegating parents park in Blocked and resume as a new attempt (in-worktree + resume prompt) once all children reach a terminal bucket. Decisions honored (child-done=In Review; partial-failure=resume-and-report with lifetime-capped retry). Full suite + e2e green. | NULL | 2026-07-17T22:05:04Z | |
| 019f7177-cfd5-7641-8d4d-068b0d5d7342 | ah-0ge.3 | closed | Eugene Blikh | Block→wait→resume join implemented and tested together: blocked promoted to a real state; delegating parents park in Blocked and resume as a new attempt (in-worktree + resume prompt) once all children reach a terminal bucket. Decisions honored (child-done=In Review; partial-failure=resume-and-report with lifetime-capped retry). Full suite + e2e green. | NULL | 2026-07-17T22:05:05Z | |
| 019f7189-c38c-7724-8d90-f041fd5f9945 | ah-gs7 | claimed | Eugene Blikh | {"id":"ah-gs7","title":"Ultrapack designer/validator roles via config + skills (human-scheduled)","description":"Ultrapack (github.com/bigbes/ultrapack) is an OpenCode pack, but its value is the skills (udesign/uplan/uexecute/uverify/ureview), and pi implements the Agent Skills standard — so the skills load unmodified via --skill with no porting. Stage 2 already delivers --skill materialization, task_types and per-task frontmatter roles, so multi-role work needs ZERO daemon code today: add designer/validator roles to config pointing at ultrapack skill packages under skills_dir, and let a human drag cards between them. State carries between runs in docs/tasks/\u003cslug\u003e.md on the task branch. Do this BEFORE automating the handoff (ah-0ge slice): it validates whether the roles are actually good while the orchestration is still free.\nUltrapack agents/ do NOT get ported — see the delegation-loop beads; agents become roles, not subagents.","design":"Roles are {model, prompt} today (internal/config/config.go:72). Fork ultrapack skills into skills_dir packages; rewrite @implementer/@explorer/@reviewer subagent references (uplan/SKILL.md:126-128, uexecute/SKILL.md:37, handsoff/SKILL.md:35) out of the skill bodies — pi has no @-mention dispatch. Designer role MUST use ultrapack's handsoff skill: udesign/SKILL.md says 'Nothing is planned or written until the user approves', which deadlocks a board-driven run until the watchdog kills it as stalled.","acceptance_criteria":"A task labeled for the designer role produces a docs/tasks/\u003cslug\u003e.md with a Design section and lands In Review without stalling; dragging it to Ready under the validator role produces a review against that same file on the same branch.","notes":"HEADLESS BEHAVIOR VERIFIED 2026-07-17 (opencode/claude-haiku-4-5, pi -p --mode json, udesign loaded via --skill on a throwaway repo): the designer run did NOT deadlock. 9 turns, read/bash/write tools, stopReason=stop, and it WROTE docs/tasks/mul-div.md following udesign's structure (Invariants/Principles/Assumptions/Unknowns + TDD decision).\n\nCRITICAL REQUIREMENT for the designer role prompt: this only worked because the rendered PROMPT explicitly neutralized udesign's collaborative-approval framing — 'No human is available; you will not receive a reply; make reasonable assumptions and record them; do not end by asking a question; WRITE the result to \u003cpath\u003e'. A naive 'design X' prompt would likely trigger the skill's 'nothing until the user approves' path and land In Review with only a question and no artifact. So prompts/designer.md MUST carry the autonomy+write-artifact framing (a lighter alternative to loading the full handsoff skill; both work). Same pattern will apply to validator/ureview.\n\nAside: openai-codex provider on this box is a ChatGPT account and rejects some models (gpt-5.2 -\u003e 400 invalid_request). Use opencode/* or deepseek/* for local pi tests; daemon uses litellm anyway.","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:25Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T15:52:13Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-17T22:24:41Z |
| 019f71a0-564c-7eb9-a545-c7361f7fd991 | ah-6ei | created | Eugene Blikh | NULL | 2026-07-17T22:49:21Z | ||
| 019f71a0-5836-775a-9670-45d171549cb0 | ah-gs7 | updated | Eugene Blikh | {"id":"ah-gs7","title":"Ultrapack designer/validator roles via config + skills (human-scheduled)","description":"Ultrapack (github.com/bigbes/ultrapack) is an OpenCode pack, but its value is the skills (udesign/uplan/uexecute/uverify/ureview), and pi implements the Agent Skills standard — so the skills load unmodified via --skill with no porting. Stage 2 already delivers --skill materialization, task_types and per-task frontmatter roles, so multi-role work needs ZERO daemon code today: add designer/validator roles to config pointing at ultrapack skill packages under skills_dir, and let a human drag cards between them. State carries between runs in docs/tasks/\u003cslug\u003e.md on the task branch. Do this BEFORE automating the handoff (ah-0ge slice): it validates whether the roles are actually good while the orchestration is still free.\nUltrapack agents/ do NOT get ported — see the delegation-loop beads; agents become roles, not subagents.","design":"Roles are {model, prompt} today (internal/config/config.go:72). Fork ultrapack skills into skills_dir packages; rewrite @implementer/@explorer/@reviewer subagent references (uplan/SKILL.md:126-128, uexecute/SKILL.md:37, handsoff/SKILL.md:35) out of the skill bodies — pi has no @-mention dispatch. Designer role MUST use ultrapack's handsoff skill: udesign/SKILL.md says 'Nothing is planned or written until the user approves', which deadlocks a board-driven run until the watchdog kills it as stalled.","acceptance_criteria":"A task labeled for the designer role produces a docs/tasks/\u003cslug\u003e.md with a Design section and lands In Review without stalling; dragging it to Ready under the validator role produces a review against that same file on the same branch.","notes":"HEADLESS BEHAVIOR VERIFIED 2026-07-17 (opencode/claude-haiku-4-5, pi -p --mode json, udesign loaded via --skill on a throwaway repo): the designer run did NOT deadlock. 9 turns, read/bash/write tools, stopReason=stop, and it WROTE docs/tasks/mul-div.md following udesign's structure (Invariants/Principles/Assumptions/Unknowns + TDD decision).\n\nCRITICAL REQUIREMENT for the designer role prompt: this only worked because the rendered PROMPT explicitly neutralized udesign's collaborative-approval framing — 'No human is available; you will not receive a reply; make reasonable assumptions and record them; do not end by asking a question; WRITE the result to \u003cpath\u003e'. A naive 'design X' prompt would likely trigger the skill's 'nothing until the user approves' path and land In Review with only a question and no artifact. So prompts/designer.md MUST carry the autonomy+write-artifact framing (a lighter alternative to loading the full handsoff skill; both work). Same pattern will apply to validator/ureview.\n\nAside: openai-codex provider on this box is a ChatGPT account and rejects some models (gpt-5.2 -\u003e 400 invalid_request). Use opencode/* or deepseek/* for local pi tests; daemon uses litellm anyway.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-17T14:37:25Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T19:24:42Z","started_at":"2026-07-17T19:24:42Z"} | {"notes":"DELIVERED + COMMITTED (982694f) 2026-07-17. Artifacts: skills/design (adapted from ultrapack udesign — autonomous, no wait-for-approval, records ### Decisions), skills/validate (single-agent review distilled from ultrapack ureview's reviewer criteria — confidence\u003e=80, severity-tiered, never edits code), prompts/designer.md + prompts/validator.md (autonomy framing verified to prevent headless stalls), config.example.yaml wiring (skills_dir=skills, designer/validator roles, type:design/type:review task_types), README Roles section.\n\nCOMPONENT-VERIFIED headless on pi 0.73.1 (opencode/claude-haiku-4-5): both skills load under --no-skills via --skill; designer produced docs/tasks/multiply-and-divide.md with full ## Design + IV/PC/AS/UK + TDD + ### Decisions, clean stop, no stall; validator wrote ## Review with a changes-requested verdict and did NOT edit code. config.example loads (TestLoadExample green).\n\nNOT verified: the literal live daemon+board flow (label-\u003etask_type-\u003erole-\u003erun) — infra-gated. Tracked as a follow-up depending on ah-k23.\n\nDesign notes: udesign/ureview were ADAPTED not vendored verbatim — udesign is collaborative and references ultrapack-only skills (uplan/handsoff/references), and ureview is built around a dispatcher+@reviewer split that doesn't fit a single agent. The @-subagent references live only in the executor skills (uexecute/uplan/handsoff/ureview), so designer+validator needed minimal @-rewrite."} | NULL | 2026-07-17T22:49:21Z |
| 019f71a0-5c13-77f7-b936-8d446f050376 | ah-gs7 | closed | Eugene Blikh | Designer/validator roles delivered and component-verified (skills + prompts + config, committed 982694f); both roles produce the right artifacts headless on pi 0.73.1. Live daemon+board acceptance tracked as a follow-up gated on ah-k23 infra. | NULL | 2026-07-17T22:49:22Z | |
| 019f71b6-eeed-7943-ad8a-f8d3bd54ca45 | ah-0ge.4 | created | Eugene Blikh | NULL | 2026-07-17T23:14:01Z | ||
| 019f71b6-f14b-7dd3-a606-c8cdb012792c | ah-0ge | updated | Eugene Blikh | {"id":"ah-0ge","title":"Stage 4: agent tools API, question loop, AgentsView links","description":"Per SPEC SS14.4: per-task bearer tokens; ahub tool task-create/ask-user/memory-search/memory-add over loopback HTTP; server-side policies (Triage-only, gen\u003c=2, per-session caps, dedup, project allowlist); question.json -\u003e Question bucket -\u003e comment-answer -\u003e pi --session resume as new attempt; parent auto-Block/unblock on subtask completion; AgentsView: pg push from runner host + /sessions/\u003cid\u003e deep links in comments.","status":"open","priority":3,"issue_type":"epic","owner":"bigbes@gmail.com","created_at":"2026-07-12T23:36:29Z","created_by":"Eugene Blikh","updated_at":"2026-07-12T23:36:29Z"} | {"notes":"STATUS 2026-07-17. The FILE-CHANNEL agent capabilities of Stage 4 are DONE and committed (9ec9418, 5ad253a): task-create (ah-0ge.1), parent block/unblock join + pi-session-style resume (ah-0ge.2/.3), ask-user question loop (ah-0ge.4). These use .task/*.json + board state instead of the per-task-bearer-token ahub-tool-over-HTTP API, which the file channel makes optional for the 'agent stops then resumes' pattern.\n\nREMAINING epic scope is infra/external-service gated and NOT autonomously completable by me:\n- memory search/add tools -\u003e depend on Stage 3 mem0 (ah-ydx); mem0 REST client is unverifiable without a live mem0 instance and I'd be guessing at its API shape.\n- AgentsView /sessions/ deep links -\u003e need 'pg push from the runner host' + a deployed AgentsView (ah-k23 infra); the deep-link URL alone is useless without the push.\n- per-task bearer tokens + ahub tool CLI-over-HTTP -\u003e an alternative transport to the file channel; only needed for mid-run (not stop-and-resume) tools, and lower value now that the file channel covers task-create + ask-user.\n\nRecommend: keep this epic open for the HTTP-tools-API + AgentsView items, to be done alongside ah-k23 infra."} | NULL | 2026-07-17T23:14:02Z |
| 019f71b7-2805-7c11-ae23-f0c35a60c537 | ah-0ge.4 | closed | Eugene Blikh | Ask-user question loop implemented and tested (committed 5ad253a): question state, .task/question.json file channel, stateless answer detection via comment sentinel, resume-with-answer. Full suite + e2e green. | NULL | 2026-07-17T23:14:16Z | |
| 019f71bf-f66b-7b27-911f-c7f82a964b2a | ah-k23 | claimed | Eugene Blikh | {"id":"ah-k23","title":"Infra: phoebe-lab wiring for agents-dev","description":"Tracked in ~/data/home/phoebe-lab (deploy via labng). Runtime setup: Vikunja project+buckets+API token+webhook target; LiteLLM virtual key for agents (budget-capped); mem0 m0sk key; srht agent-hub user + repo ACLs; later: Proxmox VM (lab.yml remote entry, basic-vmagent host, VM-local singbox for TG egress — decided: VM-local, not LAN-published), agentsview pg-push firewall allowlist for the VM.","status":"open","priority":3,"issue_type":"epic","owner":"bigbes@gmail.com","created_at":"2026-07-12T23:36:30Z","created_by":"Eugene Blikh","updated_at":"2026-07-12T23:36:30Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-17T23:23:53Z |
| 019f71d2-6c20-78d1-955b-52247f3ea910 | ah-1nu | created | Eugene Blikh | NULL | 2026-07-17T23:44:03Z | ||
| 019f71f4-e9f4-7b90-b813-7d9256ddda31 | ah-1nu | updated | Eugene Blikh | {"id":"ah-1nu","title":"BUG: vikunja Snapshot mis-parses real Vikunja 2.3.0 kanban response (buckets-with-tasks, not flat tasks)","description":"Found by the first live board test on agent-1 (Vikunja v2.3.0, project 2). internal/vikunja snapshotOnce GETs /projects/{id}/views/{kanbanView}/tasks and decodes the body as a FLAT []wireTask. But real Vikunja 2.3.0 returns a LIST OF BUCKETS, each with an embedded tasks[] array: item fields are {id(=bucket id), title(=bucket title), project_view_id, limit, count, position, tasks:[...]}. So the daemon reads the 9 buckets as 9 pseudo-tasks with bucket_id=0 (unmapped -\u003e ignored) and NEVER descends into bucket.tasks[]. A task correctly placed in Ready (verified: task 1 nested in bucket 8 with bucket_id 8) is invisible to the daemon; it claims nothing and its store has zero task rows.\n\nThe unit/e2e fakes (internal/vikunja/vikunja_test.go serveTasks, e2e fake_vikunja) return the FLAT shape the daemon expects, so all tests pass against a fixture that does not match reality — the Snapshot path has never actually run against a real board despite SPEC §9 claiming 'verified against Vikunja 2.3.0'.\n\nFIX: snapshotOnce must parse the bucket-with-tasks response — iterate buckets, and for each task in bucket.tasks set BucketID = bucket.id (task.bucket_id is also populated). Reconsider pagination (the kanban response is bucket-structured, likely one page of buckets, tasks possibly paginated per bucket via limit/count/position). Update BOTH fakes to emit the real shape so tests validate reality, and re-verify live. Sample of the real shape is available from the live API.\n\nDEPLOY: origin git@git.srht.bigb.es:~bigbes/agents-dev; a push triggers builds.sr.ht CI which scp's the binary to agent-1. Fix is code-only; deploy needs a push.","acceptance_criteria":"After the fix, dragging a card to Ready on Vikunja project 2 results in the daemon claiming it (worktree + run) and landing it In Review; fakes emit the bucket-with-tasks shape and a regression test covers it.","status":"open","priority":1,"issue_type":"bug","owner":"bigbes@gmail.com","created_at":"2026-07-17T20:44:03Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T20:44:03Z"} | {"notes":"FIXED IN CODE + tested 2026-07-18 (committed f0d6634). snapshotOnce now parses []wireBucketTasks (buckets with embedded tasks[]), flattens, maps task.bucket_id-\u003ecanonical, with a truncation guard replacing the old page-cap. Removed the flat-task pagination machinery (maxPages, pagination-header cross-checks). BOTH fakes (unit vikunja_test + e2e fake_vikunja) rewritten to emit the real bucket-with-tasks shape, so tests validate reality; added flatten/unmapped + truncation regression tests. Full unit suite + e2e green. LIVE re-verification on agent-1 still pending a deploy of the fixed binary."} | NULL | 2026-07-18T00:21:43Z |
| 019f71fb-eefb-77c4-baf5-b78ed3c3517a | ah-1nu | closed | Eugene Blikh | Fixed (f0d6634) AND verified live on agent-1 2026-07-18. After deploying the fixed binary, the daemon claimed task 1 from Ready, created worktree agent/task-1, ran pi (deepseek via LiteLLM), the agent wrote GREETING.md ('Hello from agenthubd.'), committed 7bb3e26, and the task landed In Review with a diff-stat. The Snapshot bug is dead and the bucket-shape parse is proven against real Vikunja 2.3.0. | NULL | 2026-07-18T00:29:23Z | |
| 019f71fb-f0c5-7101-b7d7-b3e02e63baa2 | ah-k23 | updated | Eugene Blikh | {"id":"ah-k23","title":"Infra: phoebe-lab wiring for agents-dev","description":"Tracked in ~/data/home/phoebe-lab (deploy via labng). Runtime setup: Vikunja project+buckets+API token+webhook target; LiteLLM virtual key for agents (budget-capped); mem0 m0sk key; srht agent-hub user + repo ACLs; later: Proxmox VM (lab.yml remote entry, basic-vmagent host, VM-local singbox for TG egress — decided: VM-local, not LAN-published), agentsview pg-push firewall allowlist for the VM.","status":"in_progress","priority":3,"issue_type":"epic","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-12T23:36:30Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T20:23:54Z","started_at":"2026-07-17T20:23:54Z"} | {"notes":"FULL PIPELINE VERIFIED LIVE 2026-07-18. End-to-end proof: a card in Ready on project 2 -\u003e daemon claims -\u003e worktree -\u003e pi(deepseek/LiteLLM) -\u003e agent implements + commits -\u003e In Review with diff-stat. Required, beyond the model wiring: (1) the vikunja Snapshot bug fix ah-1nu (deployed manually: cross-compiled linux/amd64, scp'd to /opt/agent-hub/bin, restarted; backup at agenthubd.bak.*); (2) a PATH fix — the unit had no PATH so the daemon couldn't find ahub-run in /opt/agent-hub/bin. Applied live as drop-in /etc/systemd/system/agenthubd.service.d/10-path.conf AND baked into the repo unit (phoebe-lab agent-hub/systemd/agenthubd.service) for reproducibility.\n\nREMAINING sub-item (non-blocking): review-branch push to srht 403 — the agent lacks push creds to git.srht.bigb.es:~bigbes/agent-demo (config review_remote is https; needs a token or an SSH key on the agenthub user added to srht ACLs). The run still succeeds and lands In Review; only the optional review-branch publish fails. This is the 'srht agent-hub user + repo ACLs' item. Other deferred: mem0 (Stage 3), agentsview pg-push (Stage 5)."} | NULL | 2026-07-18T00:29:24Z |
| 019f71fb-f2d1-7284-b559-59c619dbe082 | ah-tc2 | created | Eugene Blikh | NULL | 2026-07-18T00:29:24Z | ||
| 019f7390-d0b0-7c38-b0fe-fd90512751e1 | ah-tc2 | closed | Eugene Blikh | Fixed + verified live 2026-07-18. Gave the agenthub user an ed25519 SSH key (/var/lib/agenthub/.ssh/id_ed25519), registered its pubkey on bigbes' srht account via a direct meta GraphQL createSSHKey mutation (hut CLI failed on a fingerprint schema mismatch vs this self-hosted srht version; key id 2). srht git SSH is on PORT 2222 (not 22 — :22 is the host sshd). agenthub ~/.ssh/config maps git.srht.bigb.es -> Port 2222 + IdentityFile + accept-new. Switched the live config review_remote from https to git@git.srht.bigb.es:~bigbes/agent-demo. Verified: agenthub authenticates ('Hi bigbes!'), a manual branch push succeeds, and a fresh daemon run (attempt 2) landed In Review WITH the review link and no 403. SECURITY NOTE: the key is on bigbes' own account -> push access to all ~bigbes repos. Least-privilege alternative (a dedicated agent-hub srht user + per-repo ACL) is deferred; acceptable for the agent-demo sandbox. | NULL | 2026-07-18T07:51:38Z | |
| 019f7391-95b9-7962-9acb-af26ac4d3c3c | ah-k23 | updated | Eugene Blikh | {"id":"ah-k23","title":"Infra: phoebe-lab wiring for agents-dev","description":"Tracked in ~/data/home/phoebe-lab (deploy via labng). Runtime setup: Vikunja project+buckets+API token+webhook target; LiteLLM virtual key for agents (budget-capped); mem0 m0sk key; srht agent-hub user + repo ACLs; later: Proxmox VM (lab.yml remote entry, basic-vmagent host, VM-local singbox for TG egress — decided: VM-local, not LAN-published), agentsview pg-push firewall allowlist for the VM.","notes":"FULL PIPELINE VERIFIED LIVE 2026-07-18. End-to-end proof: a card in Ready on project 2 -\u003e daemon claims -\u003e worktree -\u003e pi(deepseek/LiteLLM) -\u003e agent implements + commits -\u003e In Review with diff-stat. Required, beyond the model wiring: (1) the vikunja Snapshot bug fix ah-1nu (deployed manually: cross-compiled linux/amd64, scp'd to /opt/agent-hub/bin, restarted; backup at agenthubd.bak.*); (2) a PATH fix — the unit had no PATH so the daemon couldn't find ahub-run in /opt/agent-hub/bin. Applied live as drop-in /etc/systemd/system/agenthubd.service.d/10-path.conf AND baked into the repo unit (phoebe-lab agent-hub/systemd/agenthubd.service) for reproducibility.\n\nREMAINING sub-item (non-blocking): review-branch push to srht 403 — the agent lacks push creds to git.srht.bigb.es:~bigbes/agent-demo (config review_remote is https; needs a token or an SSH key on the agenthub user added to srht ACLs). The run still succeeds and lands In Review; only the optional review-branch publish fails. This is the 'srht agent-hub user + repo ACLs' item. Other deferred: mem0 (Stage 3), agentsview pg-push (Stage 5).","status":"in_progress","priority":3,"issue_type":"epic","assignee":"Eugene Blikh","owner":"bigbes@gmail.com","created_at":"2026-07-12T23:36:30Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T21:29:24Z","started_at":"2026-07-17T20:23:54Z"} | {"notes":"RUNTIME WIRING COMPLETE — full pipeline proven live incl. review-branch publish (2026-07-18). agenthubd on agent-1 runs board tasks end-to-end: Ready -\u003e claim -\u003e worktree -\u003e pi(deepseek/LiteLLM) -\u003e commit -\u003e In Review with diff-stat AND a review link (agent branch pushed to srht). Everything on the bead's critical path is done: VM (agent-1), Vikunja project 2 + 9 buckets, LiteLLM budget-capped virtual key, pi models.json, unit PATH fix (ahub-run), srht push credential (agenthub SSH key, port 2222). Fixes made this session also flushed out and closed the vikunja Snapshot bug (ah-1nu). Deferred sub-items belong to other epics: mem0 m0sk key (Stage 3 ah-ydx), agentsview pg-push firewall allowlist (Stage 5 ah-oeq). VM-local singbox TG egress superseded by Prism/ntfy. Repo edits committed to phoebe-lab (4a2e9b1: unit PATH + CLAUDE.md); live-only changes (config, models.json, ssh key, PATH drop-in) applied on agent-1 and documented in agent-hub/CLAUDE.md."} | NULL | 2026-07-18T07:52:28Z |
| 019f73a0-b91f-7cc9-9636-fa29d5679077 | ah-6ei | claimed | Eugene Blikh | {"id":"ah-6ei","title":"Live end-to-end verification of designer/validator roles on a real board","description":"ah-gs7 delivered the design/validate skills + designer/validator role prompts + config wiring, all component-verified (skills load in pi 0.73.1; both roles produce the right artifacts headless; config.example loads). The ONE piece not yet exercised is the literal daemon flow: board card labeled type:design -\u003e daemon claims -\u003e designer role runs via LiteLLM -\u003e lands In Review with a Design doc -\u003e moved to Ready under type:review -\u003e validator writes a ## Review. Needs the phoebe-lab infra (Vikunja board + LiteLLM + real pi/zellij). Depends on ah-k23.","acceptance_criteria":"On a live board: a type:design card lands In Review with docs/tasks/\u003cslug\u003e.md ## Design; relabeled type:review and set Ready, it produces a ## Review against that same file on the same branch.","status":"open","priority":3,"issue_type":"task","owner":"bigbes@gmail.com","created_at":"2026-07-17T19:49:21Z","created_by":"Eugene Blikh","updated_at":"2026-07-17T19:49:21Z"} | {"assignee":"Eugene Blikh","status":"in_progress"} | NULL | 2026-07-18T08:09:00Z |