Skip to content

Bug: Mayor cannot edit bead dependencies — missing at every layer #1100

@jrf0110

Description

@jrf0110

Parent

Part of #204 (Phase 4: Hardening)

Problem

The Mayor cannot add or remove bead dependencies after creation. Bead dependency relationships (bead_dependencies table) are set at creation time via gt_sling_batch and are immutable after that — there are no write methods, no HTTP endpoints, no Mayor tools, and no UI for modifying the dependency graph.

Additionally, gt_sling (single bead) has no depends_on parameter at all, so you cannot create dependency relationships between individually slung beads.

This was missed in #1076 (Mayor edit tools PR), which added gt_bead_update, gt_bead_reassign, gt_bead_delete, and other edit capabilities but did not cover dependency editing.

The Gap (every layer)

Layer File Status
Core write functions src/dos/town/beads.ts No addBeadDependency() / removeBeadDependency() — only reads + cascade delete
TownDO public methods src/dos/Town.do.ts No RPC methods for dependency CRUD
HTTP endpoints src/gastown.worker.ts No routes for adding/removing dependencies
Handler src/handlers/mayor-tools.handler.ts No dependency handler
Client container/plugin/client.ts No client methods for dependencies
Mayor tools container/plugin/mayor-tools.ts No gt_bead_add_dependency / gt_bead_remove_dependency
gt_sling tool container/plugin/mayor-tools.ts:25-61 No depends_on parameter (only gt_sling_batch supports it)

Read-only dependency functions exist in beads.ts: getBeadDependencies(), getConvoyDependencyEdges(), hasUnresolvedBlockers(), getNewlyUnblockedBeads().

Fix

Full vertical slice:

1. Core functions (beads.ts)

  • addBeadDependency(sql, beadId, dependsOnBeadId, type) — insert into bead_dependencies with cycle detection
  • removeBeadDependency(sql, beadId, dependsOnBeadId) — delete from bead_dependencies
  • Cycle detection is critical — reuse the Kahn's algorithm validation from slingConvoy() (Town.do.ts:1879-1915) or extract it into a shared utility

2. TownDO methods (Town.do.ts)

  • addBeadDependency(beadId, dependsOnBeadId, type) — validates both beads exist, calls core function, logs bead event
  • removeBeadDependency(beadId, dependsOnBeadId) — validates dependency exists, calls core function, logs bead event
  • After removing a dependency, check if any beads become unblocked via getNewlyUnblockedBeads() and arm the alarm for dispatch

3. HTTP endpoints (gastown.worker.ts)

  • POST /api/towns/:townId/rigs/:rigId/beads/:beadId/dependencies — body: { depends_on_bead_id, dependency_type }
  • DELETE /api/towns/:townId/rigs/:rigId/beads/:beadId/dependencies/:dependsOnBeadId
  • User auth (not agent-scoped), consistent with the other PATCH endpoints from feat(gastown): add mayor edit tools and manual editing UI #1076

4. Mayor tools (mayor-tools.ts)

  • gt_bead_add_dependency — params: bead_id, depends_on_bead_id, dependency_type (default 'blocks')
  • gt_bead_remove_dependency — params: bead_id, depends_on_bead_id

5. gt_sling enhancement

Add an optional depends_on parameter to gt_sling (single bead) accepting an array of bead IDs. This enables creating dependency chains between individually slung beads, not just within convoys.

Acceptance Criteria

  • addBeadDependency() and removeBeadDependency() core functions in beads.ts with cycle detection
  • TownDO RPC methods with validation and bead event logging
  • HTTP endpoints for dependency CRUD with user auth
  • gt_bead_add_dependency and gt_bead_remove_dependency Mayor tools
  • gt_sling accepts optional depends_on bead IDs
  • Removing a dependency triggers unblocked-bead check and dispatch
  • Cycle detection prevents creating circular dependencies

Notes

  • No data migration needed
  • The bead_dependencies table has a unique index on (bead_id, depends_on_bead_id) — duplicate adds should be a no-op or a clear error, not a crash
  • Dependency type enum is 'blocks' | 'tracks' | 'parent-child'. The Mayor tools should default to 'blocks' since that's the semantic for work ordering. 'tracks' is for convoy membership (system-managed), 'parent-child' is for molecules.
  • The Mayor prompt's "Surgical Editing" section should be updated to document the new dependency tools

Metadata

Metadata

Assignees

No one assigned

    Labels

    kilo-duplicateAuto-generated label by Kilokilo-triagedAuto-generated label by Kilo

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions