~bigbes/agents-dev · parade

main · last commit 13 days ago · 7g0stsfu

← Back to the parade

ah-0ge.2 Parent auto-Block/unblock join on child completion Past Stand

status: closed P3 feature @Eugene Blikh
bd reopen ah-0ge.2
Created byEugene Blikh
Ownerbigbes@gmail.com
Created2026-07-17T14:38:03Z
Started2026-07-17T17:45:37Z
Updated2026-07-17T19:05:05Z
Closed2026-07-17T19:05:05Z
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.
UNSPECIFIED 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
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.

STATE 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.

BEHAVIOR: 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.

Tests: 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.

NOTE/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).

Depends on

  • ah-0ge.1 — Agent-created tasks via .task/tasks.json file channel blocks closed
  • ah-0ge — Stage 4: agent tools API, question loop, AgentsView links parent-child closed

Depended on by

  • ah-0ge.3 — Resume parent via pi --session with child results as a new attempt blocks

Prerequisite chain — everything this waits on, transitively

  • ah-0ge.1 — Agent-created tasks via .task/tasks.json file channel blocks closed
  • ah-0ge — Stage 4: agent tools API, question loop, AgentsView links parent-child closed
  • ah-9r4 — DECISION: worktree/branch topology for agent-created child tasks blocks closed

No comments.

Close reason

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.
  • Eugene Blikh added under epic ah-0ge · 2026-07-17T17:38:02Z
  • Eugene Blikh created the issue · 2026-07-17T17:38:02Z
  • Eugene Blikh added dependency on ah-0ge.1 · 2026-07-17T17:38:39Z
  • Eugene Blikh ah-0ge.3 now depends on this · 2026-07-17T17:38:40Z
  • Eugene Blikh claimed · 2026-07-17T20:45:36Z
  • Eugene Blikh updated notes to 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). DELIVERED (green, GOFLAGS=-mod=readonly): - store schema v3: task_parents(child_id PK, parent_id, generation, created_at) + migration [2]->[3]. - ports.Store + store: RecordChild, GenerationOf, ChildIDsOf (idempotent on child_id). - config.AgentTasks.MaxGeneration (default 2, must be positive). - reconcile.spawnChildTasks now enforces the depth cap (a task at generation >= MaxGeneration cannot delegate; childGen = parentGen+1) and records each child's lineage on creation; 'spawned_tasks' event carries generation. - 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. ARCHITECTURAL FINDING (blocks the join; needs a decision): ah-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'). DECISIONS captured for the join (from the user): child counts as done at IN REVIEW (not Done); partial failure -> resume the parent reporting each child's outcome, parent may retry a couple of times (bounded by MaxGeneration + a future per-parent round cap). RECOMMENDATION: 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. · 2026-07-17T20:55:27Z
  • Eugene Blikh updated notes to 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. STATE 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. BEHAVIOR: 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. Tests: 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. NOTE/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). · 2026-07-17T22:05:03Z
  • Eugene Blikh closed the issue · 2026-07-17T22:05:04Z
    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.
  • Eugene Blikh added label milestone:stage-4 · 2026-07-20T03:08:47Z
  • Eugene Blikh removed label milestone:stage-4 · 2026-07-20T03:10:28Z
Stored rows — what this pane was built from, as read
issues 1 row
id ah-0ge.2
content_hash cc37ff5a5860feb86cb3556e7841450c187af1c9a8c3899f32e4f991134e9e1b
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. UNSPECIFIED 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.
design
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 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. STATE 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. BEHAVIOR: 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. Tests: 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. NOTE/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).
status closed
priority 3
issue_type feature
assignee Eugene Blikh
estimated_minutes NULL
created_at 2026-07-17T14:38:03Z
created_by Eugene Blikh
owner bigbes@gmail.com
updated_at 2026-07-17T19:05:05Z
closed_at 2026-07-17T19:05:05Z
closed_by_session
external_ref NULL
spec_id
compaction_level 0
compacted_at NULL
compacted_at_commit NULL
original_size NULL
sender
ephemeral 0
wisp_type
pinned 0
is_template 0
mol_type
work_type
source_system
metadata �{}
source_repo
close_reason 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.
event_kind
actor
target
payload
await_type
await_id
timeout_ns 0
waiters
hook_bead
role_bead
agent_state
last_activity NULL
role_type
rig
due_at NULL
defer_until NULL
no_history 0
started_at 2026-07-17T17:45:37Z
is_blocked 0
dependencies 3 rows
id 37350a43-d1cf-589c-ad21-f1a995e71e61
issue_id ah-0ge.3
type blocks
created_at 2026-07-17T17:38:40Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-0ge.2
depends_on_wisp_id NULL
depends_on_external NULL
id 5e2253b1-6d56-5425-9481-7de7669b5d9f
issue_id ah-0ge.2
type blocks
created_at 2026-07-17T17:38:39Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-0ge.1
depends_on_wisp_id NULL
depends_on_external NULL
id 89451810-b9c9-5774-8dfa-d2150d295f85
issue_id ah-0ge.2
type parent-child
created_at 2026-07-17T17:38:02Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-0ge
depends_on_wisp_id NULL
depends_on_external NULL
events 7 rows
id 019f7083-5495-7c7b-970f-1c7fe985f283
issue_id ah-0ge.2
event_type created
actor Eugene Blikh
old_value
new_value
comment NULL
created_at 2026-07-17T17:38:02Z
id 019f712f-0ce2-79eb-b2de-26915f09aef8
issue_id ah-0ge.2
event_type claimed
actor Eugene Blikh
old_value {"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"}
new_value {"assignee":"Eugene Blikh","status":"in_progress"}
comment NULL
created_at 2026-07-17T20:45:36Z
id 019f7138-1076-7d84-9b11-fdb4d8a0cf24
issue_id ah-0ge.2
event_type updated
actor Eugene Blikh
old_value {"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"}
new_value {"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."}
comment NULL
created_at 2026-07-17T20:55:27Z
id 019f7177-caa8-7d75-bf84-df653d118195
issue_id ah-0ge.2
event_type updated
actor Eugene Blikh
old_value {"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"}
new_value {"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)."}
comment NULL
created_at 2026-07-17T22:05:03Z
id 019f7177-ce38-7e4c-9efc-a9431043c0ae
issue_id ah-0ge.2
event_type closed
actor Eugene Blikh
old_value
new_value 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.
comment NULL
created_at 2026-07-17T22:05:04Z
id 019f7cda-9636-7e53-b88f-1e232d84293e
issue_id ah-0ge.2
event_type label_added
actor Eugene Blikh
old_value NULL
new_value NULL
comment Added label: milestone:stage-4
created_at 2026-07-20T03:08:47Z
id 019f7cdc-1f2a-7105-b15d-6b003d3566d9
issue_id ah-0ge.2
event_type label_removed
actor Eugene Blikh
old_value NULL
new_value NULL
comment Removed label: milestone:stage-4
created_at 2026-07-20T03:10:28Z