Skip to content
quarry Timeline
Login

Timeline

Parents and children of check-in [526e25a5d6]

2026-08-17
00:57
tickets: display them the way fossil models them

The page dumped every folded field into one table, which read as noise and lost most of the ticket. Fossil's model has three parts and quarry was collapsing all of them into one:

- Scalar state (status, priority, resolution…) folds last-write-wins. - A leading + is the APPEND form: 'J +comment more' grows the field rather than replacing it. quarry stored a separate field literally named '+comment' — sqlite's tickets use it 255 times. - icomment belongs to the CHANGE, never to the ticket. Folding it left one comment standing where a conversation was: the busiest tcl ticket showed 1 of its 84.

Per-change plumbing (icomment, mimetype, login, username) no longer appears as ticket state. The page now leads with the title, shows fossil's header order, renders the description and every comment through their own recorded mimetype, and attributes each — including fossil's 'claiming to be' when the typed name differs from the login, which on an open tracker it may.

Verified on tcl 408840ff: 11 clean fields, 84 comments, 5 attachments. check-in: 9ac012f7f2 user: dmestas tags: trunk

00:32
notify: address repo activity as a topic, with a key notify accepts

Running the real companion found two faults no stub would have.

NotifyEvent.To is documented as "a user, or a repo:<name> topic", but quarry put that string in subscriberId. notify addresses the two through DIFFERENT fields, so an activity event did not fan out — it invented a subscriber literally named repo:synthetic and every watcher heard nothing. Verified against notify: the message existed, addressed to nobody real.

notify also refuses a topic key containing a colon (lowercase, digits, hyphen, underscore only) and rejects the whole trigger, so quarry's own convention could never have been a valid key. repoTopicKey translates at the boundary; quarry keeps its internal vocabulary. Names differing only in punctuation or case collapse to one key, which is documented rather than hashed away — an operator has to be able to read the key they subscribe someone to.

End to end on a real notify + dagnats: a wiki save reaches every member of repo-synthetic, an @mention reaches the person, and both render in quarry's inbox. check-in: 526e25a5d6 user: dmestas tags: trunk

00:19
notify: authenticate triggers, and embed the inbox

Two things, one of them a live bug. notify's /v1 routes sit behind an API-key middleware and quarry's client sent no Authorization header, so every trigger it fired would have been answered 401. It went unnoticed because --notify was never configured and a trigger failure is logged rather than raised. --notify-key (or QUARRY_NOTIFY_KEY) supplies it, and serve says so at startup when it is missing rather than leaving the answer to be discovered in the log.

The inbox is notify's, embedded (0001 §5): GET /v1/messages?channel=in_app for the signed-in account, rendered with unread emphasised. quarry models no notification state — it displays what notify owns.

The wire field names are notify's Go field names: its domain.Message carries db tags but no json tags, so the encoder falls back to the identifiers. A test pins that, since decoding lowercase would silently produce empty subjects.

An outage is not emptiness: a failed fetch says notifications are unavailable instead of showing an empty list, which would be a lie about whether anyone had written to you. check-in: e33f1c4e8c user: dmestas tags: trunk