hubtask

module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2026 License: Apache-2.0

README

Hubtask

A task manager that is genuinely yours — for one person, a household, a team, and a provider who runs it for thousands of others — built with the seriousness of infrastructure: nothing is lost, nothing leaks between workspaces, every guarantee can be checked.

  • One model for a life and a client roster. "Buy milk" and a release plan live in the same five levels — Hub → Collection → Task → Work Package → Activity — without becoming two products.
  • Yours to run. One image and PostgreSQL, docker compose up, the full feature set, no licence key that switches anything off, nothing that phones home. The same image runs a multi-tenant platform on Kubernetes.
  • Everything you can click, a script and an agent can do too — through a REST API, an MCP server, webhooks, n8n and Zapier, and a rule engine, under the same permissions, recorded in the same trail. AI is optional and can be switched off.
  • It keeps your work safe and says so. Backups to a target you choose, encrypted and restored in a drill; a chained audit trail that verifies; deletion that announces itself and can be stopped; a health report that names what is missing instead of failing silently.
  • Private by design. The boundary between workspaces is held by the database; a person's rights over their data are answered in the product, on time; everything can be exported, always.
  • Offline, and nothing lost. Clients keep working without a network, and concurrent changes are merged without losing anyone's work.
  • Every person sees what is theirs to use — a control that may not be used is not shown — in any language, time zone and text direction.
  • Open source under Apache-2.0.

The vision behind this, the people it is for and the settings it must work in are in docs/vision/.


Documentation

The architecture is fully documented. docs/README.md says where each kind of knowledge lives; start with the vision (why), the use cases (what must be true for a person) and arc42 (how it is built). AGENTS.md is how to work here, for a person or a coding agent.


The architecture in one paragraph

One Go module, one container image, several process roles (api, worker, scheduler, automation). The core (core/) is technology-free and knows only ports; REST, MCP, calendar, mail, and webhooks are adapters. PostgreSQL is the only mandatory dependency and handles storage, the job queue, the event outbox, full-text search, and tenant isolation (row level security). Instead of four specialised level entities there is one generalised WorkItem aggregate root with capability profiles — new levels and fields are configuration, not a migration.

The same repository also holds both first-party clients and the design system (ADR-0027): the web UI under apps/webapp is an inbound adapter like REST or MCP and ships inside the binary (ADR-0028), and the project website lives under apps/website.


Quick start

git clone https://github.com/Jersyfi/hubtask.git && cd hubtask
cp deploy/docker/.env.example .env      # set the secrets
docker compose -f deploy/docker/compose.yaml up -d
# API:  http://localhost:8080/api/v1
# Meta: http://localhost:8080/api/v1/meta/capabilities

Kubernetes:

helm upgrade --install hubtask ./k8s -f ./k8s/values.yaml

The command line client

hubctl signs in with a personal access token and speaks the published contract — its types are generated from api/openapi.yaml. Every command prints a table for a person, or, with --json, the API's own payload for a pipe: exactly one document on standard output and every diagnostic on standard error.

make build                                   # bin/hubctl
echo "$TOKEN" | bin/hubctl auth login --url http://localhost:8080
HUB=$(bin/hubctl container create --type HUB --name "Personal" | awk 'NR==2 {print $1}')
bin/hubctl container create --type COLLECTION --parent "$HUB" --name "Errands"
bin/hubctl item create --collection "$COLLECTION" --type TASK --title "Buy milk"
bin/hubctl item complete "$ITEM"
bin/hubctl comment add "$ITEM" --body "Done on the way home"
bin/hubctl search milk
bin/hubctl trash ls
bin/hubctl watch                             # follow the change stream; Ctrl-C ends it
bin/hubctl sync pull --all > state.jsonl     # the offline synchronisation, as a device: the cursor last
bin/hubctl sync push --file queue.jsonl      # one mutation per line; one result per line back
bin/hubctl sync devices ls                   # and `sync devices forget <id>`
bin/hubctl sync snapshot --out state.ndjson --apply   # the initial synchronisation as one stream; the cursor is the last line
bin/hubctl import trello board.json --hub "$HUB" --wait 5m   # also csv, google-tasks, microsoft-todo; the report on the run

bin/hubctl due set "$ITEM" --at 2026-09-10   # a day; a timestamp is a moment instead
bin/hubctl remind add "$ITEM" --at -PT30M    # half an hour before it is due
bin/hubctl recur set "$ITEM" --rule "FREQ=WEEKLY;BYDAY=MO" --zone Europe/Berlin
bin/hubctl template instantiate "$TEMPLATE" --collection "$COLLECTION" --anchor 2026-09-07
bin/hubctl view export "$VIEW" --format ICS --out week.ics
bin/hubctl calendar mint --view "$VIEW"      # prints the feed URL once; it is the credential

The automation surface, and the inbox it can act on:

RULE=$(bin/hubctl rule add --name "mail becomes a task" --trigger JUMBLE_ENTRY \
  --run-as "$ACCOUNT" \
  --action 'CONVERT_JUMBLE_ENTRY:{"collection_id":"'"$COLLECTION"'"}' | awk 'NR==2 {print $1}')
bin/hubctl rule test "$RULE" --event de.hubtask.jumble.entry.received.v1   # the dry run
bin/hubctl rule enable "$RULE"               # a rule is written switched off, always
bin/hubctl rule runs --rule "$RULE"          # what it has done, newest first
bin/hubctl rule run show "$RUN"              # one run, step by step

bin/hubctl jumble intake rotate-token        # the address the inbox accepts deliveries on, once
bin/hubctl jumble ls --status NEW
bin/hubctl jumble convert "$ENTRY" --collection "$COLLECTION"
bin/hubctl jumble dismiss "$ENTRY"           # a state, not a deletion

WEBHOOK=$(bin/hubctl webhook add --url https://example.org/hooks \
  --event de.hubtask.work.item.completed.v1 | awk 'NR==2 {print $1}')
bin/hubctl webhook deliveries "$WEBHOOK" --status FAILED
bin/hubctl webhook replay "$WEBHOOK" "$DELIVERY"   # the same event id, so a repeat is recognisable
bin/hubctl webhook rotate-secret "$WEBHOOK" --grace 0   # 0 retires the old one at once

bin/hubctl events poll de.hubtask.work.item.completed.v1 --since "$CURSOR"

What an operator does with an installation is the same client:

TARGET=$(bin/hubctl backup target add --name nightly --kind LOCAL --config path=daily | awk 'NR==2 {print $1}')
bin/hubctl backup target test "$TARGET"
bin/hubctl backup run --target "$TARGET" --follow --wait 30m
bin/hubctl backup ls --target "$TARGET"       # what is actually lying at the target
bin/hubctl backup verify "$RUN" --follow      # fails the command if it does not verify
bin/hubctl backup schedule set "$SCHEDULE" --trial   # every FULL run is followed by an INSPECT of its own archive

bin/hubctl restore inspect --target "$TARGET" --archive "$ARCHIVE"
bin/hubctl restore run --target "$TARGET" --archive "$ARCHIVE" --mode NEW_TENANT --apply
                                              # a dry run with a report until --apply is typed
bin/hubctl retention add --kind COMPLETED_ITEM --days 90 --action TRASH
bin/hubctl retention preview "$POLICY"        # what it would take, and what stands in the way
bin/hubctl hold place --scope CONTAINER --id "$COLLECTION" --reason "the Meier proceedings"
bin/hubctl audit query --from 2026-08-01 --action auth.
bin/hubctl audit verify --from 2026-08-01 --to 2026-09-01   # red when the chain does not hold
bin/hubctl dsr create --kind ERASURE --subject "$ACCOUNT"
bin/hubctl dsr start "$CASE" --mode ANONYMIZE # the transition that runs the work
bin/hubctl job show "$JOB" --follow

Errors are the message catalogue's sentences rather than the problem document behind them — the server emits codes, never display text (ADR-0011). Which platforms the binary is supported on is in support-matrix.md §4.


Technology

Area Choice
Language Go (≥ 1.27), net/http, log/slog
Database PostgreSQL 16+ (pgx/v5, sqlc, goose)
API OpenAPI 3.1 spec-first (oapi-codegen), RFC 9457, cursor pagination
Events Transactional outbox, CloudEvents 1.0, optionally NATS JetStream
Automation Declarative rules, conditions in CEL (cel-go)
Scheduling RFC 5545 RRULE (rrule-go), PostgreSQL job queue
AI MCP server; AI port with adapters for OpenAI-compatible APIs and Ollama
Object storage S3 or any S3-compatible service, or a local volume
Observability OpenTelemetry, Prometheus; dashboards, alert rules, and runbooks included
Resilience Circuit breakers, bulkheads, load shedding, dead letter, idempotency throughout
Backup Own logical archive format (JSON Lines + manifest), AES-256-GCM, adapters for S3/SFTP/FTPS/WebDAV/SMB/Azure/GCS/rclone/local
Offline sync Delta sync via a change log, hybrid logical clocks, OR-sets, fractional indices
Clients Svelte 5 + TypeScript; the webapp as a plain Vite SPA, served from inside the binary; Tauri 2 shells for desktop and mobile planned
Design system Design tokens (W3C DTCG, Style Dictionary) as the single origin of every visual value; pnpm workspace
Deployment Docker/Podman Compose, Helm for Kubernetes

Licence

Hubtask is open source under the Apache License 2.0 — free for any use, commercial included, with the full feature set and no licence key (ADR-0080, licensing-editions.md). The name and the logo are covered by TRADEMARK.md, not by the licence. Donations fund the work — see the funding section.


Contributing

Conventional Commits, trunk-based development, Definition of Ready/Done from engineering-guidelines.md. Architectural changes arrive as an ADR, not as a pull request without context. See CONTRIBUTING.md, SECURITY.md, and CODE_OF_CONDUCT.md.

Directories

Path Synopsis
cmd
hubctl command
Command hubctl is the command line client for a Hubtask installation.
Command hubctl is the command line client for a Hubtask installation.
migrate command
Command migrate applies the database migrations.
Command migrate applies the database migrations.
restore-drill command
Command restore-drill is RT-9: the proof that the installation's point-in-time recovery works, run where the data is (backup-restore.md §8.5, ADR-0046).
Command restore-drill is RT-9: the proof that the installation's point-in-time recovery works, run where the data is (backup-restore.md §8.5, ADR-0046).
server command
Command server starts Hubtask in one or more roles (ADR-0014).
Command server starts Hubtask in one or more roles (ADR-0014).
core
application/archive
Package archive is the Hubtask archive format of backup-restore.md §3: what a backup writes and what a restore reads, as a reader and a writer over the backup target port.
Package archive is the Hubtask archive format of backup-restore.md §3: what a backup writes and what a restore reads, as a reader and a writer over the backup target port.
application/catalogue
Package catalogue is the list of every use case this build has, once.
Package catalogue is the list of every use case this build has, once.
application/condition
Package condition is the vocabulary an expression may use, and the shape of what it is told.
Package condition is the vocabulary an expression may use, and the shape of what it is told.
application/repository/activity
Package activity declares how an item's history is written and how it is read back.
Package activity declares how an item's history is written and how it is read back.
application/repository/admin
Package admin holds the control plane's outbound ports (multi-tenancy.md §5).
Package admin holds the control plane's outbound ports (multi-tenancy.md §5).
application/repository/audit
Package audit declares how the evidence trail is read back.
Package audit declares how the evidence trail is read back.
application/repository/automation
Package automation is the repository port of the rules (automation.md §1).
Package automation is the repository port of the rules (automation.md §1).
application/repository/backup
Package backup is the outbound port for the targets a tenant has configured.
Package backup is the outbound port for the targets a tenant has configured.
application/repository/idempotency
Package idempotency declares what the idempotency guard needs from storage.
Package idempotency declares what the idempotency guard needs from storage.
application/repository/identity
Package identity declares what the identity use cases need from storage.
Package identity declares what the identity use cases need from storage.
application/repository/importer
Package importer is the outbound side of an import: the run's repository, and the converter port - a foreign file in, archive records out.
Package importer is the outbound side of an import: the run's repository, and the converter port - a foreign file in, archive records out.
application/repository/integration
Package integration holds the repository ports of what reaches into this system from outside it: today the calendar feeds, later the webhook subscriptions beside them.
Package integration holds the repository ports of what reaches into this system from outside it: today the calendar feeds, later the webhook subscriptions beside them.
application/repository/job
Package job is the outbound port for background work as a caller sees it.
Package job is the outbound port for background work as a caller sees it.
application/repository/jumble
Package jumble is the repository port of the inbox (domain-model.md §2).
Package jumble is the repository port of the inbox (domain-model.md §2).
application/repository/lifecycle
Package lifecycle declares what the end of data's life needs stored: the instructions not to delete, and the record of what was deleted anyway.
Package lifecycle declares what the end of data's life needs stored: the instructions not to delete, and the record of what was deleted anyway.
application/repository/mail
Package mail is the store of a workspace's mail intake (ADR-0094): its settings, the receipts of what it received, and the lookups that route a message.
Package mail is the store of a workspace's mail intake (ADR-0094): its settings, the receipts of what it received, and the lookups that route a message.
application/repository/media
Package media declares what the media use cases need from storage of the *records* - the rows beside the bytes.
Package media declares what the media use cases need from storage of the *records* - the rows beside the bytes.
application/repository/meta
Package meta declares what the self-description needs from storage.
Package meta declares what the self-description needs from storage.
application/repository/notification
Package notification declares what the notification path needs from storage: the records it writes, and the preferences it honours.
Package notification declares what the notification path needs from storage: the records it writes, and the preferences it honours.
application/repository/outbox
Package outbox declares how a domain event leaves the write path.
Package outbox declares how a domain event leaves the write path.
application/repository/privacy
Package privacy declares what data subject rights need stored: the case, the consent, and the two marks an erasure leaves on things it does not delete.
Package privacy declares what data subject rights need stored: the case, the consent, and the two marks an erasure leaves on things it does not delete.
application/repository/quota
Package quota holds the outbound ports of the §4 limits (multi-tenancy.md).
Package quota holds the outbound ports of the §4 limits (multi-tenancy.md).
application/repository/sealing
Package sealing is the census a rotation ends on (ADR-0045, security.md §8.1): how many stored values still name each master key, and in which kind of value.
Package sealing is the census a rotation ends on (ADR-0045, security.md §8.1): how many stored values still name each master key, and in which kind of value.
application/repository/streams
Package streams holds the outbound port of the partitioned streams' maintenance: activity entries, outbox events and rule runs partition by month, the leader keeps the coming months existing, and the retention engine drops what has wholly aged out.
Package streams holds the outbound port of the partitioned streams' maintenance: activity entries, outbox events and rule runs partition by month, the leader keeps the coming months existing, and the retention engine drops what has wholly aged out.
application/repository/suggestion
Package suggestion is the outbound port of what AI proposed.
Package suggestion is the outbound port of what AI proposed.
application/repository/sync
Package sync declares what offline clients need recorded about a change.
Package sync declares what offline clients need recorded about a change.
application/repository/view
Package view declares how the application layer stores saved views.
Package view declares how the application layer stores saved views.
application/repository/voice
Package voice is the store of a workspace's voice settings (ADR-0093).
Package voice is the store of a workspace's voice settings (ADR-0093).
application/repository/work
Package work declares what the work management use cases need from storage.
Package work declares what the work management use cases need from storage.
application/service/access
Package access decides whether an actor may do something.
Package access decides whether an actor may do something.
application/service/admin
Package admin holds the control plane's use cases: the lifecycle of a tenant, as multi-tenancy.md §5 draws it.
Package admin holds the control plane's use cases: the lifecycle of a tenant, as multi-tenancy.md §5 draws it.
application/service/audit
Package audit is the trail as somebody reads it: a page of it, an archive of it, and the check that it has not been rewritten (audit.md §5).
Package audit is the trail as somebody reads it: a page of it, an archive of it, and the check that it has not been rewritten (audit.md §5).
application/service/automation
Package automation holds the use cases that write the rules (automation.md §1).
Package automation holds the use cases that write the rules (automation.md §1).
application/service/backup
Package backup is where an operator says where backups go, and finds out whether they can (backup-restore.md §2).
Package backup is where an operator says where backups go, and finds out whether they can (backup-restore.md §2).
application/service/idempotency
Package idempotency makes a repeated write harmless.
Package idempotency makes a repeated write harmless.
application/service/identity
Package identity holds the use cases that turn a credential into an actor.
Package identity holds the use cases that turn a credential into an actor.
application/service/importer
Package importer is an import from another system (backup-restore.md §9): the use case that accepts one, the read that answers its report, and the job that runs it.
Package importer is an import from another system (backup-restore.md §9): the use case that accepts one, the read that answers its report, and the job that runs it.
application/service/integration
Package integration holds the use cases that let another system reach into this one, and this one reach out: today the webhook subscriptions, later the trigger polling and the jumble's inbound routes.
Package integration holds the use cases that let another system reach into this one, and this one reach out: today the webhook subscriptions, later the trigger polling and the jumble's inbound routes.
application/service/job
Package job is the caller's half of the queue: finding out how a piece of background work is getting on, and stopping it.
Package job is the caller's half of the queue: finding out how a piece of background work is getting on, and stopping it.
application/service/jumble
Package jumble holds the use cases of the inbox (domain-model.md §5): something arrives, is listed, and becomes work or ages out.
Package jumble holds the use cases of the inbox (domain-model.md §5): something arrives, is listed, and becomes work or ages out.
application/service/lifecycle
Package lifecycle is where data stops existing: the hard delete, and the rules that decide when it is allowed (ADR-0020, data-retention.md).
Package lifecycle is where data stops existing: the hard delete, and the rules that decide when it is allowed (ADR-0020, data-retention.md).
application/service/mail
Package mail is the administration of a workspace's mail intake (ADR-0094): its settings, its log, a collection's handle, and the address a notification's reply goes to.
Package mail is the administration of a workspace's mail intake (ADR-0094): its settings, its log, a collection's handle, and the address a notification's reply goes to.
application/service/media
Package media is the upload life of a file: staged, carried to storage by somebody other than this server, confirmed, and eventually reclaimed (arc42 §8.4).
Package media is the upload life of a file: staged, carried to storage by somebody other than this server, confirmed, and eventually reclaimed (arc42 §8.4).
application/service/meta
Package meta answers what this installation is and what it can do.
Package meta answers what this installation is and what it can do.
application/service/notification
Package notification is the application half of the Notification context: the consumer that turns events into records, and the delivery that turns a record into a message.
Package notification is the application half of the Notification context: the consumer that turns events into records, and the delivery that turns a record into a message.
application/service/platform
Package platform writes the installation's events: what a provider's purchase platform learns about a workspace (UC-INS-14, multi-tenancy.md §4.3).
Package platform writes the installation's events: what a provider's purchase platform learns about a workspace (UC-INS-14, multi-tenancy.md §4.3).
application/service/privacy
Package privacy is data subject rights as use cases rather than as a support process (data-protection.md §4, ADR-0018 decision 4).
Package privacy is data subject rights as use cases rather than as a support process (data-protection.md §4, ADR-0018 decision 4).
application/service/quota
Package quota turns multi-tenancy.md §4's table into enforcement: per-tenant limits from `tenant.settings.quotas` with the mode's defaults, one resolution, one refusal shape.
Package quota turns multi-tenancy.md §4's table into enforcement: per-tenant limits from `tenant.settings.quotas` with the mode's defaults, one resolution, one refusal shape.
application/service/sealing
Package sealing is the half of a key rotation that lets it finish (ADR-0045, security.md §8.1).
Package sealing is the half of a key rotation that lets it finish (ADR-0045, security.md §8.1).
application/service/suggestion
Package suggestion is the application layer of what AI proposed.
Package suggestion is the application layer of what AI proposed.
application/service/sync
Package sync is the application half of the change stream: what a client is allowed to be told about, and where in the log it stands (ADR-0021).
Package sync is the application half of the change stream: what a client is allowed to be told about, and where in the log it stands (ADR-0021).
application/service/voice
Package voice turns what a person says to a voice assistant into work (ADR-0093): entries put on a list, a list read out, an entry ticked off, the day's due entries told.
Package voice turns what a person says to a voice assistant into work (ADR-0093): entries put on a list, a list read out, an entry ticked off, the day's due entries told.
application/service/work
Package work holds the work management use cases: containers and the items inside them.
Package work holds the work management use cases: containers and the items inside them.
application/shared
Package shared holds what every use case needs regardless of its context: who is acting, in which tenant, with which permissions, and in which language the answer is to be rendered.
Package shared holds what every use case needs regardless of its context: who is acting, in which tenant, with which permissions, and in which language the answer is to be rendered.
application/usecase
Package usecase is the catalogue: every use case the system has, once.
Package usecase is the catalogue: every use case the system has, once.
domain/event
Package event holds the domain events: what happened, in a form other systems can subscribe to.
Package event holds the domain events: what happened, in a form other systems can subscribe to.
domain/model/activity
Package activity holds an item's own history: what happened to a piece of work, in the words the people working on it read (arc42 §5.2, the "Audit & Activity" context).
Package activity holds an item's own history: what happened to a piece of work, in the words the people working on it read (arc42 §5.2, the "Audit & Activity" context).
domain/model/automation
Package automation holds the rule: what starts a run, what has to be true for it to go on, and what it then does (automation.md §1, ADR-0009).
Package automation holds the rule: what starts a run, what has to be true for it to go on, and what it then does (automation.md §1, ADR-0009).
domain/model/backup
Package backup is where a backup goes and what has to be true before it may go there (backup-restore.md §2, ADR-0019).
Package backup is where a backup goes and what has to be true before it may go there (backup-restore.md §2, ADR-0019).
domain/model/entitlement
Package entitlement holds the features a plan may leave out of a workspace (multi-tenancy.md §4.2), and what a workspace makes of the set its plan leaves out.
Package entitlement holds the features a plan may leave out of a workspace (multi-tenancy.md §4.2), and what a workspace makes of the set its plan leaves out.
domain/model/identity
Package identity holds the model of who acts: accounts, their credentials, and the tokens that stand in for them when nobody is at a keyboard.
Package identity holds the model of who acts: accounts, their credentials, and the tokens that stand in for them when nobody is at a keyboard.
domain/model/importer
Package importer is an import from another system (backup-restore.md §9): a file somebody exported elsewhere, converted into the records a backup archive holds and applied through the restore.
Package importer is an import from another system (backup-restore.md §9): a file somebody exported elsewhere, converted into the records a backup archive holds and applied through the restore.
domain/model/integration
Package integration holds the model of what reaches into this system from outside it, or lets something outside read it: today the calendar feed, later the webhooks that share its table section in the schema.
Package integration holds the model of what reaches into this system from outside it, or lets something outside read it: today the calendar feed, later the webhooks that share its table section in the schema.
domain/model/job
Package job is background work as the caller who asked for it sees it.
Package job is background work as the caller who asked for it sees it.
domain/model/jumble
Package jumble is the inbox before the work exists (domain-model.md §2): entries arrive over four channels - a mail, a webhook, a quick capture, a plain API call - and become work items by conversion, or age out by dismissal.
Package jumble is the inbox before the work exists (domain-model.md §2): entries arrive over four channels - a mail, a webhook, a quick capture, a plain API call - and become work items by conversion, or age out by dismissal.
domain/model/lifecycle
Package lifecycle is the bounded context that decides when data stops existing: retention rules, the safeguards that override them, and the record of what was removed (ADR-0020, data-retention.md).
Package lifecycle is the bounded context that decides when data stops existing: retention rules, the safeguards that override them, and the record of what was removed (ADR-0020, data-retention.md).
domain/model/mail
Package mail is the mail intake's own rules (ADR-0094): where a message is meant to go - read off its subject and the address it was sent to - and who may write at all.
Package mail is the mail intake's own rules (ADR-0094): where a message is meant to go - read off its subject and the address it was sent to - and who may write at all.
domain/model/media
Package media is the Media context's domain: what an uploaded object is, and how it may be served (arc42 §5.2).
Package media is the Media context's domain: what an uploaded object is, and how it may be served (arc42 §5.2).
domain/model/notification
Package notification is the Notification context arc42 §5.2 names: what somebody is to be told, what they have said about being told it, and how far that got.
Package notification is the Notification context arc42 §5.2 names: what somebody is to be told, what they have said about being told it, and how far that got.
domain/model/plan
Package plan holds a plan: a provider's group of workspaces with its own limits, locked values and the features it leaves out, between the installation and the workspace (multi-tenancy.md §4.2, ADR-0086).
Package plan holds a plan: a provider's group of workspaces with its own limits, locked values and the features it leaves out, between the installation and the workspace (multi-tenancy.md §4.2, ADR-0086).
domain/model/privacy
Package privacy is the bounded context of data subject rights (data-protection.md §4, ADR-0018): the case somebody's exercised right becomes, the deadline it carries, and the consent that can be taken back.
Package privacy is the bounded context of data subject rights (data-protection.md §4, ADR-0018): the case somebody's exercised right becomes, the deadline it carries, and the consent that can be taken back.
domain/model/shared
Package shared holds the vocabulary every bounded context needs: identifiers, locales, and the error model.
Package shared holds the vocabulary every bounded context needs: identifiers, locales, and the error model.
domain/model/suggestion
Package suggestion is what AI proposed, and did not do (ADR-0012).
Package suggestion is what AI proposed, and did not do (ADR-0012).
domain/model/sync
Package sync holds the offline synchronisation context's own entities (offline-sync.md §10): what the server keeps about the devices that synchronise, beside the change log they read.
Package sync holds the offline synchronisation context's own entities (offline-sync.md §10): what the server keeps about the devices that synchronise, beside the change log they read.
domain/model/view
Package view holds the query language every view is drawn from: the filter grammar of api-guidelines.md §3, what may be asked of which field, and the bounds a query has to stay inside.
Package view holds the query language every view is drawn from: the filter grammar of api-guidelines.md §3, what may be asked of which field, and the bounds a query has to stay inside.
domain/model/voice
Package voice is what a spoken sentence means to Hubtask (ADR-0093): the things named, their amounts and the place they go.
Package voice is what a spoken sentence means to Hubtask (ADR-0093): the things named, their amounts and the place they go.
domain/model/work
Package work holds the model of what is being managed: containers, items, and the policy that says what each kind of item can do.
Package work holds the model of what is being managed: containers, items, and the policy that says what each kind of item can do.
domain/service
Package service holds the domain services: the rules that belong to no single entity.
Package service holds the domain services: the rules that belong to no single entity.
port/ai
Package ai is the outbound half of ADR-0012: the port through which this product may ask a model something, and never a dependency of anything inwards of it.
Package ai is the outbound half of ADR-0012: the port through which this product may ask a model something, and never a dependency of anything inwards of it.
port/audit
Package audit is the port for the evidence trail (audit.md, ADR-0017).
Package audit is the port for the evidence trail (audit.md, ADR-0017).
port/backupstorage
Package backupstorage is the port a backup target sits behind (backup-restore.md §2, ADR-0019).
Package backupstorage is the port a backup target sits behind (backup-restore.md §2, ADR-0019).
port/clock
Package clock is the port for the one thing that makes otherwise pure code untestable: the current time.
Package clock is the port for the one thing that makes otherwise pure code untestable: the current time.
port/crypto
Package crypto is the port for keeping a value unreadable to whoever holds the storage it sits on (backup-restore.md §4, security.md §8).
Package crypto is the port for keeping a value unreadable to whoever holds the storage it sits on (backup-restore.md §4, security.md §8).
port/environment
Package environment is the port for the entire configuration.
Package environment is the port for the entire configuration.
port/eventbus
Package eventbus is the port for the delivery half of the outbox (ADR-0007).
Package eventbus is the port for the delivery half of the outbox (ADR-0007).
port/expression
Package expression is what a condition is, and nothing about how one is evaluated.
Package expression is what a condition is, and nothing about how one is evaluated.
port/health
Package health carries the health model from ADR-0016.
Package health carries the health model from ADR-0016.
port/httpclient
Package httpclient is the port for calls that leave the process: webhooks, automation actions, AI providers, OIDC discovery.
Package httpclient is the port for calls that leave the process: webhooks, automation actions, AI providers, OIDC discovery.
port/i18n
Package i18n is the port for the declared exception to rule 8.
Package i18n is the port for the declared exception to rule 8.
port/identityprovider
Package identityprovider is the relying-party half of ADR-0005, as the application layer needs it: send somebody to their company's provider, and turn what comes back into a verified identity.
Package identityprovider is the relying-party half of ADR-0005, as the application layer needs it: send somebody to their company's provider, and turn what comes back into a verified identity.
port/mail
Package mail is the port for the one notification channel that sends (arc42 §5.2).
Package mail is the port for the one notification channel that sends (arc42 §5.2).
port/mailbox
Package mailbox is how the mail intake reads a connected mailbox (ADR-0094 decision 1): sign in, take the messages not yet taken, move each to the done folder once it is filed.
Package mailbox is how the mail intake reads a connected mailbox (ADR-0094 decision 1): sign in, take the messages not yet taken, move each to the done folder once it is filed.
port/passkey
Package passkey is the seam the application layer checks a WebAuthn ceremony through (identity.md §23, ADR-0085).
Package passkey is the seam the application layer checks a WebAuthn ceremony through (identity.md §23, ADR-0085).
port/persistence
Package persistence is the port for transactional storage.
Package persistence is the port for transactional storage.
port/queue
Package queue is the port for work that happens outside a request: the job queue, the handlers that run on it, and the leader that exists exactly once (ADR-0008).
Package queue is the port for work that happens outside a request: the job queue, the handlers that run on it, and the leader that exists exactly once (ADR-0008).
port/recurrence
Package recurrence is the port for reading an RFC 5545 recurrence rule and turning it into the moments it means (ADR-0008, arc42 §11 R-07).
Package recurrence is the port for reading an RFC 5545 recurrence rule and turning it into the moments it means (ADR-0008, arc42 §11 R-07).
port/stepup
Package stepup is the seam a destructive act asks for a second, stronger proof of identity through (identity.md §16, backup-restore.md §8.3, security.md §5).
Package stepup is the seam a destructive act asks for a second, stronger proof of identity through (identity.md §16, backup-restore.md §8.3, security.md §5).
port/storage
Package storage is the port for object storage: the bytes a person attaches to their work (arc42 §5.2 Media, §8.4).
Package storage is the port for object storage: the bytes a person attaches to their work (arc42 §5.2 Media, §8.4).
port/text
Package text is the port for the two things the domain has to do to text and may not do itself (i18n-l10n.md §5, §7): bring an input to its Unicode normal form, and bring the domain half of an address to the ASCII form a mail server sees.
Package text is the port for the two things the domain has to do to text and may not do itself (i18n-l10n.md §5, §7): bring an input to its Unicode normal form, and bring the domain half of an address to the ASCII form a mail server sees.
shared/concurrency
Package concurrency is the only place in the project where a `go` statement may appear.
Package concurrency is the only place in the project where a `go` statement may appear.
shared/correlation
Package correlation carries the request-scoped identifiers that every signal is joined on: the request ID and the tenant (observability-reliability.md §3.1).
Package correlation carries the request-scoped identifiers that every signal is joined on: the request ID and the tenant (observability-reliability.md §3.1).
shared/secret
Package secret provides a type that cannot accidentally be written to a log.
Package secret provides a type that cannot accidentally be written to a log.
Package db carries the migrations into the binary.
Package db carries the migrations into the binary.
infrastructure
ai
Package ai holds the outbound AI adapters (ADR-0012, ADR-0049).
Package ai holds the outbound AI adapters (ADR-0012, ADR-0049).
alexa
Package alexa proves that a request came from Alexa (ADR-0093): the signing certificate is fetched only from Amazon's own address, its chain is verified against the system's roots and names echo-api.amazon.com, and the body's SHA-256 signature is checked with its key.
Package alexa proves that a request came from Alexa (ADR-0093): the signing certificate is fetched only from Amazon's own address, its chain is verified against the system's roots and names echo-api.amazon.com, and the body's SHA-256 signature is checked with its key.
audit
Package audit writes the evidence trail and keeps its chain (audit.md §3, ADR-0017).
Package audit writes the evidence trail and keeps its chain (audit.md §3, ADR-0017).
automation
Package automation runs what a rule decided to do.
Package automation runs what a rule decided to do.
awssig
Package awssig is AWS Signature Version 4 over the standard library, with two callers: the media object store and the backup target.
Package awssig is AWS Signature Version 4 over the standard library, with two callers: the media object store and the backup target.
backupstorage
Package backupstorage holds the adapters behind core/port/backupstorage: the four protocols ADR-0019 opens with, and the conformance suite BK-1 holds every one of them to.
Package backupstorage holds the adapters behind core/port/backupstorage: the four protocols ADR-0019 opens with, and the conformance suite BK-1 holds every one of them to.
clock
Package clock is the adapter behind the clock port.
Package clock is the adapter behind the clock port.
crypto
Package crypto is the adapter behind core/port/crypto: AES-256-GCM envelope encryption over a keyring the environment supplies, and Argon2id where a key has to come from a passphrase (backup-restore.md §4, security.md §8).
Package crypto is the adapter behind core/port/crypto: AES-256-GCM envelope encryption over a keyring the environment supplies, and Argon2id where a key has to come from a passphrase (backup-restore.md §4, security.md §8).
environment
Package environment is the adapter for the configuration port: it reads HUBTASK_* variables.
Package environment is the adapter for the configuration port: it reads HUBTASK_* variables.
eventbus
Package eventbus renders domain events in the format subscribers read.
Package eventbus renders domain events in the format subscribers read.
expression
Package expression evaluates conditions with CEL (ADR-0009).
Package expression evaluates conditions with CEL (ADR-0009).
health
Package health implements the health port.
Package health implements the health port.
httpclient
Package httpclient is the only way out of the process.
Package httpclient is the only way out of the process.
i18n
Package i18n renders message codes into sentences.
Package i18n renders message codes into sentences.
importer
Package importer holds the converters: one per foreign format, each turning a file into the archive records the restore applies.
Package importer holds the converters: one per foreign format, each turning a file into the archive records the restore applies.
instancefile
Package instancefile is the third door to the instance level (ADR-0070 §5, the concept's §5.4).
Package instancefile is the third door to the instance level (ADR-0070 §5, the concept's §5.4).
mail
Package mail is the outbound adapter for the mail port: SMTP, and the health probe that reads the same breaker it trips.
Package mail is the outbound adapter for the mail port: SMTP, and the health probe that reads the same breaker it trips.
mailbox
Package mailbox reads connected mailboxes for the mail intake (ADR-0094): IMAP spoken here, in the few commands a read needs, and JMAP over the guarded HTTP client.
Package mailbox reads connected mailboxes for the mail intake (ADR-0094): IMAP spoken here, in the few commands a read needs, and JMAP over the guarded HTTP client.
observability
Package observability holds the adapters for logging, metrics and tracing.
Package observability holds the adapters for logging, metrics and tracing.
oidc
Package oidc is the relying party, and the only package in this repository that knows what JOSE is (ADR-0036).
Package oidc is the relying party, and the only package in this repository that knows what JOSE is (ADR-0036).
postgres
Package postgres is the persistence adapter.
Package postgres is the persistence adapter.
postgres/query
Package query turns a validated query into the statement that answers it.
Package query turns a validated query into the statement that answers it.
recurrence
Package recurrence expands RFC 5545 rules through rrule-go (ADR-0008).
Package recurrence expands RFC 5545 rules through rrule-go (ADR-0008).
resilience
Package resilience holds the building blocks from observability-reliability.md §6: timeouts, retry, a circuit breaker, a bulkhead, and a load shedder.
Package resilience holds the building blocks from observability-reliability.md §6: timeouts, retry, a circuit breaker, a bulkhead, and a load shedder.
security
Package security holds the cryptographic primitives.
Package security holds the cryptographic primitives.
storage
Package storage holds the outbound adapters behind core/port/storage, and the upload guard in front of them: the component the upload matrix tests (SG-12, security.md T-11/T-17).
Package storage holds the outbound adapters behind core/port/storage, and the upload guard in front of them: the component the upload matrix tests (SG-12, security.md T-11/T-17).
text
Package text is the adapter for core/port/text: golang.org/x/net/idna for domains, and golang.org/x/text/unicode/norm for the Unicode normal form.
Package text is the adapter for core/port/text: golang.org/x/net/idna for domains, and golang.org/x/text/unicode/norm for the Unicode normal form.
webauthn
Package webauthn is Hubtask's own verifier of WebAuthn ceremonies (ADR-0085, identity.md §23.3): the CBOR subset, the COSE keys of ES256, EdDSA and RS256, and the checks of WebAuthn Level 3 §7.1, on the standard library alone.
Package webauthn is Hubtask's own verifier of WebAuthn ceremonies (ADR-0085, identity.md §23.3): the CBOR subset, the COSE keys of ES256, EdDSA and RS256, and the checks of WebAuthn Level 3 §7.1, on the standard library alone.
webhook
Package webhook sends one event to one subscriber (automation.md §3.1).
Package webhook sends one event to one subscriber (automation.md §3.1).
Package locales carries the message catalogues as data, and nothing else.
Package locales carries the message catalogues as data, and nothing else.
presentation
calendar
Package calendar renders RFC 5545 documents.
Package calendar renders RFC 5545 documents.
intake
Package intake is the inbound adapter for content that arrives from outside without a person behind it: the jumble's doors, the webhook intake and the mail intake.
Package intake is the inbound adapter for content that arrives from outside without a person behind it: the jumble's doors, the webhook intake and the mail intake.
mcp
Package mcp exposes the use case catalogue to agents (ai-first.md §1.1, ADR-0012).
Package mcp exposes the use case catalogue to agents (ai-first.md §1.1, ADR-0012).
openapi
Package openapi provides primitives to interact with the openapi HTTP API.
Package openapi provides primitives to interact with the openapi HTTP API.
rest
Package rest contains the inbound HTTP adapters.
Package rest contains the inbound HTTP adapters.
stream
Package stream is the machinery a long-lived connection needs, shared by every adapter that holds one.
Package stream is the machinery a long-lived connection needs, shared by every adapter that holds one.
voice
Package voice speaks Alexa's protocol (ADR-0093): a signed JSON request in, a sentence out.
Package voice speaks Alexa's protocol (ADR-0093): a signed JSON request in, a sentence out.
webui
Package webui serves the built to-do application out of the binary.
Package webui serves the built to-do application out of the binary.
worker
Package worker is the inbound adapter of the queue channel.
Package worker is the inbound adapter of the queue channel.
sdk
go/examples/quickstart command
Command quickstart is the Go SDK's example: list the collections of a hub, create an entry in the first one, read it back.
Command quickstart is the Go SDK's example: list the collections of a hub, create an entry in the first one, read it back.
go/hubtask
Package hubtask provides primitives to interact with the openapi HTTP API.
Package hubtask provides primitives to interact with the openapi HTTP API.
test
e2e/mint command
Command mint draws a personal access token and prints it beside the hash the database stores.
Command mint draws a personal access token and prints it beside the hash the database stores.
e2e/totp command
Command totp prints the code an authenticator would show for a secret, right now.
Command totp prints the code an authenticator would show for a secret, right now.
load/harness
Package harness is the load generator the resilience and load suites share.
Package harness is the load generator the resilience and load suites share.
load/seed command
Command seed writes the load dataset as PostgreSQL COPY text, one table per invocation.
Command seed writes the load dataset as PostgreSQL COPY text, one table per invocation.
resilience/rt8 command
Command rt8 puts load on a running installation and reports what it saw, so that RT-8 - a rolling update under load, with no 5xx and no data loss (observability-reliability.md §12) - is answered with numbers rather than with a look at the pods.
Command rt8 puts load on a running installation and reports what it saw, so that RT-8 - a rolling update under load, with no 5xx and no data loss (observability-reliability.md §12) - is answered with numbers rather than with a look at the pods.
tools
apicompat command
Command apicompat holds the API contract to the last release (`make gate-api-compat`, versioning-release.md §6).
Command apicompat holds the API contract to the last release (`make gate-api-compat`, versioning-release.md §6).
checkdocs command
Command checkdocs is the documentation gate (make gate-docs).
Command checkdocs is the documentation gate (make gate-docs).
checkpr command
Command checkpr holds a pull request description to the template (the job `Pull request description` in ci.yml, part of `CI required`; `make gate-pr BODY=<file>` locally).
Command checkpr holds a pull request description to the template (the job `Pull request description` in ci.yml, part of `CI required`; `make gate-pr BODY=<file>` locally).
cilocal
Package cilocal is what the pull request pipeline decides, readable outside the pipeline: the path filters of `ci.yml`'s `changes` job.
Package cilocal is what the pull request pipeline decides, readable outside the pipeline: the path filters of `ci.yml`'s `changes` job.
deprecations command
Command deprecations writes the table of deprecated request fields from api/openapi.yaml.
Command deprecations writes the table of deprecated request fields from api/openapi.yaml.
eventmatrix command
Command eventmatrix writes docs/audit/event-matrix.md from the use case catalogue.
Command eventmatrix writes docs/audit/event-matrix.md from the use case catalogue.
flowstats command
Command flowstats measures how work flows through the repository over a window of days (`make flowstats`, ADR-0089): how long a pull request takes from its first commit to the merge, what CI costs in wall clock, and - on a machine that keeps Claude Code transcripts - what a session spends waiting and how many tokens it reads.
Command flowstats measures how work flows through the repository over a window of days (`make flowstats`, ADR-0089): how long a pull request takes from its first commit to the merge, what CI costs in wall clock, and - on a machine that keeps Claude Code transcripts - what a session spends waiting and how many tokens it reads.
locales command
Command locales reports how complete each translation is (ADR-0055).
Command locales reports how complete each translation is (ADR-0055).
numbers command
Command numbers holds the numbered files - migrations and ADRs - to one file per number (`make gate-numbers`, ADR-0083).
Command numbers holds the numbered files - migrations and ADRs - to one file per number (`make gate-numbers`, ADR-0083).
openapijson command
Command openapijson writes api/openapi.yaml as api/openapi.json.
Command openapijson writes api/openapi.yaml as api/openapi.json.
sdkgen command
Command sdkgen generates the TypeScript and the Python client from api/openapi.yaml.
Command sdkgen generates the TypeScript and the Python client from api/openapi.yaml.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL