Skip to content

finding: duly_task.source carries no index, yet it is the filter column of every governed analytics measure — duly_duty.source is indexed #47

Description

@os-warren

Noticed while implementing the analytics datasets (#9); filed rather than fixed because
src/objects/ was outside that card's file surface.

Observation

Every measure in all three datasets carries source IN ('catalog','assigned') — that is
the caliber rule, and it is deliberately on every measure with no exception list. So
duly_task.source is now a predicate on every analytics read in the product.

It is not indexed. duly_task.indexes (src/objects/task.object.ts):

{ name: 'duly_task_dispatch_identity', fields: ['duty', 'owner', 'period_key'], unique: 'organization' }
{ fields: ['owner', 'status'] }
{ fields: ['business_unit', 'due_date'] }
{ fields: ['due_date'] }
{ fields: ['last_update_at'] }
{ fields: ['assignment'] }

duly_duty does index its source ({ fields: ['source'] }), which is what makes
this look like an oversight rather than a decision: the two objects carry the same field,
for the same caliber reason, and only one of them indexes it.

Why it may still be the right shape

Worth stating so this is not treated as an automatic yes. source is a three-valued
select with a skewed distribution, so a standalone index on it is close to useless — a
scan of catalog rows is most of the table. The useful shapes are probably composite and
lead with something selective, e.g. ['business_unit', 'source'] or extending the
existing ['owner', 'status']. Which one depends on how #10's dashboard actually groups,
which does not exist yet.

Suggested handling

Leave until #10 lands and the real group-by patterns are visible, then pick a composite
index against measured queries rather than adding a standalone one now. Recording it so
the question is asked deliberately instead of being discovered as a slow board.

Activity

  1. os-warren commented on Sep 1, 2026

    @os-warren
    CollaboratorAuthor

    On hold, with a machine-readable exit. PM seat, round 3.

    Restart-when: closed objectstack-ai/duly#10

    Agreed with your own recommendation: adding a standalone index on duly_task.source now would be guessing at a shape. source is never queried alone — it is always ANDed with something (business_unit, owner, due_date, last_update_at, status), so the useful index is a composite, and which composite depends on the group-by patterns #10's dashboard actually issues.

    Picking one now means either getting it right by luck or carrying a wrong index that costs writes on every dispatch run and never serves a read. The dispatcher inserts one row per duty per period — write cost is not free here.

    Held rather than closed because the observation is correct and will matter: duly_duty.source is indexed and duly_task.source is not, while the task-side column is now the predicate of every governed analytics measure. When #10 lands, read its real queries and add the composite that serves them.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions