100 Commits
Author SHA1 Message Date
zeekayandHanzo Dev fd0483569b Build the image on the Go its module requires
go.mod asks for go 1.27.1 and the builder stage was golang:1.26.8-alpine,
whose GOTOOLCHAIN=local fails that build; the publish gate refuses it
before it starts. The stage now uses golang:1.27.1-alpine and sets
GOTOOLCHAIN=auto, so a later go.mod bump fetches its Go instead of
failing.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-03 12:30:13 -07:00
zeekayandHanzo Dev 3d729057eb Enforce each namespace's retention
WorkflowExecutionRetentionTtl (default 720h) was stored and read nowhere,
so finished runs and every key they own stayed forever.

runPurge, beside the cron sweeper, now runs every 5 s across every tenant.
Each pass reads up to 512 of a namespace's run rows, workflow runs then
standalone activities, from a cursor at purge/<ns>, and removes each
terminal run whose close time plus the retention has passed: wf, wfh,
wfact, wfopen and the idem and sctrig entries naming it, or act, ahist and
the aidem entries naming it. Every delete goes through the replicated
delete path, the row last, so a pass cut short leaves the row to find the
rest by. The row is re-read under the run lock first; an open run is never
touched. A retention that does not parse purges nothing and is reported.

Each pass ends in Shard.Reclaim, and a default-mode shard is rebuilt at
the end of a walk, when it is smallest, so the file shrinks.

On a 1.71 GiB shard of 200k expired runs and 10 open ones, 392 passes
removed them (p99 197 ms a pass), the file went to 132 KiB, and Embed took
5 ms and 16 MB peak RSS.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-03 12:19:56 -07:00
zeekayandHanzo Dev 67dad01398 Recover reads only the runs still open
Recover listed every run in a namespace and decoded each one, finished runs
included, to skip all but the few still open, so a restart cost more with
every run a shard had ever held.

wfopen/<ns>/<workflowId>/<runId> now names each workflow run that is not
terminal. It is put before a run's first row and deleted after its terminal
row, so a process stopped between the two leaves an entry that recovery
drops, never an open run the index misses. Recover lists it and re-drives
what it names.

A shard written before the index is walked once, a page at a time, decoding
only each row's status and times; wfidx/<ns> records that the walk is done.

On a 1.71 GiB shard of 200k finished runs and 10 open ones, Embed went from
10.4 s and 1.25 GB peak RSS to 7.7 s and 85 MB on the boot that builds the
index, and 6.0 s and 21 MB after it. What remains is the envelope
decrypting the whole file at open.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-03 12:19:48 -07:00
zeekayandHanzo Dev 7769db3bb3 Page a shard's scans and give its free pages back
Shard.Scan reads at most limit rows of a prefix after a given key, so a
long walk holds the shard's one connection a page at a time; List is Scan
with no limit.

Shard.Reclaim returns free pages to the filesystem. A shard in incremental
auto-vacuum releases up to 4096 per call. A shard in SQLite's default mode
can only be rebuilt with VACUUM, so it is rebuilt when the caller says it is
done deleting and a quarter of it is free; the rebuild moves it to
incremental mode, so it happens once. incremental_vacuum yields a row per
page released, so it is drained as a query.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-03 12:19:29 -07:00
zeekayandHanzo Dev c39dccff47 A schedule's own fire carries the tick it was for
The sweep stamps TemporalScheduledStartTime on every run it starts: the nominal
tick (RFC 3339, UTC), not the moment the sweep got to it, so a tick fired late
after downtime and the same tick fired by a second engine carry one value. A
manual trigger is not a tick and carries none. ScheduledStart reads it back, and
View.DescribeWorkflow lets an in-process host read its own run, so a consumer
that makes one thing per tick (a cron Job) can tell a fire from a trigger.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-03 04:19:18 -07:00
zeekayandHanzo Dev 342dc736c2 LLM.md is the one committed guide; CLAUDE.md, AGENTS.md and GEMINI.md are local links to it
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-24 15:58:03 -07:00
zeekayandHanzo Dev b808c06ebc Forward the request target a caller actually named
Hanzo CI/CD / cicd (push) Failing after 7m26s
CI/CD / cicd (push) Failing after 7m27s
An adapted net/http handler was handed a request with an empty
RequestURI, so anything that routes or logs on the target saw "/" and
answered for a path nobody asked for. The pin carries the fix.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 05:59:06 -07:00
zeekayandHanzo Dev a5460ed12e Say which method each registration answers
Hanzo CI/CD / cicd (push) Failing after 6m22s
CI/CD / cicd (push) Failing after 6m23s
A registration that is not a typed operation is spelled Raw now, with the method
named, so opting out of the typed model reads as what it is.

The zip this pins also states the wire explicitly, which matters more than the
version gap suggests: JSON semantics follow the toolchain, so the older pin
answered with different bodies than the code was written against once the
builder moved.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 04:26:51 -07:00
zeekayandHanzo Dev 435c0eb107 Build on Go 1.27
Hanzo CI/CD / cicd (push) Failing after 5m41s
CI/CD / cicd (push) Failing after 5m42s
1.27 is the released toolchain and the tree already compiles clean on it, so
the go directive names it. Nothing here depends on a 1.27 language feature
yet; this is the floor moving, which is what makes generic methods, the wider
type inference and promoted-field struct literals available to the code that
wants them next.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 18:40:12 -07:00
zeekayandHanzo Dev 6cca380431 Dial ZAP clients without starting a listener
The tasks client and the SDK client dial the Tasks server and are never
started, so they bind no socket. Responses and server-pushed deliveries
arrive on the connection the client opened; with discovery off nothing
dials back.

TestZAPClientsListenNowhere asks the OS which sockets the process
listens on: the server adds one, both clients add none.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 20:20:48 -07:00
zeekayandHanzo Dev 6b231e7f05 go 1.26.8
One toolchain across the estate. The tree carried 1.26.0, .1, .3, .4 and .5
at once, so which compiler built a binary depended on which repo it came
from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 23:55:44 -07:00
zeekayandHanzo Dev b29503b794 Move the workflows to .github/workflows
The forge reads .github/workflows natively and github.com reads nothing else,
so one directory serves both planes instead of two conventions that disagree
about which one is live. The reusable in hanzoai/ci already lives there, so a
caller naming that path now resolves to a file that exists.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 18:52:14 -07:00
zeekayandHanzo Dev 9729108d19 fix: call the pipeline at the address it actually lives
hanzoai/ci keeps the reusable at .github/workflows/build.yml — the one path
both planes resolve, since github.com reads a reusable only from there and the
forge reads it too. The v1 tag moved with it, so a caller still naming
.hanzo/workflows/build.yml asks for a blob that is not in the tree:

  InsertRun: read hanzoai/ci@v1:.hanzo/workflows/build.yml: object does not exist

The caller itself stays at .hanzo/workflows/cicd.yml on purpose: github.com has
no runner for these labels, so a caller placed there could never be scheduled.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 02:20:45 -07:00
zeekayandHanzo Dev fcd3aa7c1c Merge remote-tracking branch 'origin/main'
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 00:59:50 -07:00
zeekay 9a286ccfa2 Ship the image as the binary alone
An empty image holding the static binary, the CA bundle and zoneinfo,
and the directories it writes. Nothing else is present to run.
2026-09-03 17:43:46 -07:00
zeekayandHanzo Dev 24e232722f chore: symlink AGENTS.md + GEMINI.md + CLAUDE.md -> LLM.md
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-02 02:42:56 -07:00
zeekay 8e8ff917b2 State a version once
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.

Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
2026-08-29 13:46:59 -07:00
zeekayandHanzo Dev 58ccc45b16 Merge branch 'main' of github.com:hanzoai/tasks
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-28 13:43:33 -07:00
zeekay 08e248d6f4 Name Zen in the hero card's font stack
The social card asked for Inter first. That is not a face this estate
licenses, ships or ever drew, so a renderer with Inter installed painted
the wrong face and one without it silently fell through to system-ui.
Zen leads now; the same tail follows it.
2026-08-28 11:40:02 -07:00
zeekay 86301446c5 the engine hands a composer a zip app, not a handler
A composer had one way to mount the engine: take HTTPHandler and adapt it,
which puts sixty-odd operations behind one opaque wildcard the composing
router cannot see into. Surface registers them as real routes, so
app.Use(engine.Surface()) puts every address in the composed router and in
every projection that reads it.

Both renderings reach the same functions -- a call in, an answer out --
so the two transports cannot describe one operation differently, and
HTTPHandler is unchanged for callers that have it.

The wire is held by a test rather than by intent.
TestSurfaceAnswersWhatTheMuxAnswers drives the same requests through both
and compares status, body, Content-Type and Location. It replaced a probe
that printed the two answers and asserted nothing, and the first thing it
found was real: http.ServeMux tidies a path with an empty or dot segment
and redirects to the tidied form before matching, so /namespaces//workflows
was a redirect through the mux and a 404 here. The wildcard answers that
redirect now, with the body http.Redirect writes and only for the methods
it writes one for.
2026-08-25 13:19:08 -07:00
zeekayandHanzo Dev cdca774661 One derived key, no wrapping
tasks generated a DEK per shard, wrapped it under a KEK derived from the
master, and stored the wrapped blob beside the database — so it also needed an
upgrade path to rewrap, a principal vocabulary to derive against, and tests
for all of it. hanzoai/cek derives the key from the master and the namespace
instead. Nothing is stored, so there is nothing to wrap, rewrap, or upgrade.

dek.go, principal.go and upgrade.go are gone with the tests that pinned them:
they proved properties of a scheme that no longer exists, not properties the
store still has to hold.

That also unpins hanzoai/sqlite, which deleted the DEK API in v0.5.0. tasks
now builds against it, which is what proves the migration is complete rather
than merely compiling.

Databases written under the old scheme will not open under the new
derivation. There are no customers and no data to preserve.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-02 09:45:33 -07:00
zeekayandHanzo Dev 947ef427f6 ci: point the reusable at the path that survives the WORKFLOW_DIRS narrowing
This caller already lives under .hanzo/workflows; its `uses:` did not. Reusables
are resolved through services/actions.ResolveUses, which enforces the same
directory allowlist on the REFERENCED path:

  "uses:" path %q must be under a configured workflow directory

so `hanzoai/ci/.github/workflows/build.yml@v1` stops resolving the moment
WORKFLOW_DIRS narrows to .hanzo/workflows alone. The failure mode is the one
this file already documents: the forge refuses at InsertRun, before any run row
is written, so there is no failed run to look at — pushes and workflow_dispatch
alike silently do nothing.

Safe to point at .hanzo now because the v1 channel tag moved. hanzoai/ci
66d4f21 publishes build.yml at BOTH paths from every tag, byte-identical apart
from its header, since GitHub resolves only .github/workflows and git.hanzo.ai
only .hanzo/workflows. Verified against the live remote: v1 and v2 each serve
.hanzo/workflows/build.yml as blob 1100f49a672b. Same pipeline, same @v1 — only
the path changed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 17:28:11 -07:00
zeekayandHanzo Dev e6989b9dc4 deps: platform authority is membership of the reserved org (authz v1.10.29)
PlatformSudo read the HOME org, so every real operator was denied: an operator is
anchored in a brand org where they bill and do ordinary work, and holds the
reserved org as a further membership. The anchor and the authority are different
questions.

This is what made the reserved org unreachable in practice — nobody could cut a
release or reach an admin surface — while the predicate read as though it were
working.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 17:14:56 -07:00
zeekayandHanzo Dev 9259e6f01c tasks: the edge writes identity headers, it does not mint them
Minting is issuing authority. IAM mints — it signs the token, and that
signature is where the authority is created. tasksd verifies one and
restates it as headers a transport that cannot carry a token can read.
Nothing here creates authority, so naming both operations "mint" put the
issuer's job and this service's under one word, and a word that covers
two operations is a word that stops distinguishing them.

Every place that named the header write "mint" now names it "write",
matching the leaf it already cites: hanzoai/authz names its header list
"once by the party that WRITES their values". The four ctx accessors said
"minted" for a value that is neither issued nor a header — they return
what the validated claims RESOLVED to, which is the word the org scoping
already used for Claims.EffectiveOrg.

"mint" stays where it is the right word: the test helper signing a JWT,
the `owner` claim IAM stamps at sign time, the HMAC task tokens dispatch
issues, and money mint/burn in CONTRACT.md.

LLM.md also cited edge.Inject, which no longer exists. The call is
edge.Apply — the name it took when the four readers collapsed onto one
leaf, precisely because writing headers is not injecting authority.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 16:02:10 -07:00
zeekayandHanzo Dev 4cd9de6fed tasks: the namespace org comes from the subject's membership, not the app's
authz v1.10.26: the `owner` claim carries the org of the APPLICATION a token was
minted through, so reading it as the subject's org made a person's durable state —
engine.As(Org(...)) scopes the store by it — follow whichever app they signed in
through. It is the first entry of the signed membership set now.

A token stating no org gets none, with no fallback, so tasksd refuses it when
identity is required rather than scoping a namespace to an app-selected value.

Also edge.Inject→Apply and edge.Mint→Render: minting is issuing authority and only
IAM does that.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 10:34:02 -07:00
zeekayandHanzo Dev e3636baf8e tasks: the trusted issuer is a set, and an empty entry is not one
TASKSD_WHITELABEL_ISSUERS adds the brands this tasksd accepts tokens from beyond
the primary, each of which signs its own. Adding one is configuration.

The sharp edge is the empty entry: splitting an UNSET env var yields one empty
string, and an empty trusted issuer would match a token that carries no `iss` at
all. Entries are trimmed and dropped, pinned by
TestIssuerAllowlistDropsEmptyEntries — which builds the verifier through the same
code path production uses, so the guard is tested where it runs rather than in
isolation.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 05:20:14 -07:00
zeekayandHanzo Dev f927109617 tasks: retire the fourth reader of one contract
pkg/auth held 190 lines of JWKS cache and JWT verification — a fourth independent
reading of what an IAM token means — and it had two defects the shared reader does
not:

  it verified against EVERY key in the published set and took the first that
  worked, so a token naming kid A was accepted on a signature from key B. Naming a
  key is what `kid` is for.

  its issuer comparison was CONDITIONAL on the configured issuer being non-empty,
  so an unset TASKSD_JWT_ISSUER did not fail closed — it accepted tokens from any
  issuer.

It also stripped only the four names it reads. Every other minted header —
X-User-IsAdmin and X-User-Permissions (the platform and money signals),
X-User-Owner, X-Billing-Account-Id, X-Scope, X-Workspace-Id, and the retired names
— passed through from the client untouched. tasksd terminates identity itself (its
ingress routes straight to the Service), so nothing upstream was deleting them
either. Restoring the four-name strip turns
TestRequireIdentity_StripsTheWholeEstateSet red on seven forged headers.

And it had NO machine predicate at all, so an admin-org client_credentials token
arrived as a person. It now reads the membership set, like the rest of the estate.

What remains is the part that is genuinely tasksd's: which environment variables
the policy comes from. The audience stays optional and that is deliberate rather
than an oversight — IAM sets `aud` to the requesting CLIENT (RFC 8707), and tasksd
is not a client id, so it pins the issuer and the signing keys instead.

Both transports now answer "which org does this act in" with the same function,
Claims.EffectiveOrg(""), rather than the HTTP path reading `owner` and the ZAP path
reading it separately.

Cost, measured: 342 linked packages and an 18.3 MB binary, DOWN from 345 and
18.6 MB — dropping go-jose more than paid for the leaf, and tasks links ZERO zip
packages because the edge names no transport. go-jose is gone from the module
entirely; the tests now mint with golang-jwt, the library IAM signs with.

Rebased onto 12 upstream commits: kept their ServeGated(addr string) signature,
their engine.As(Org(...)) rename, their dependency versions, and the LLM.md fact
about explicit project/user isolation. Their only change to the deleted jwt.go was
a comment naming hanzo.id, which the replacement already says.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-30 05:14:00 -07:00
zeekayandHanzo Dev 432713bae3 feat(store): tasksd upgrade — move a pre-principal store into this layout
An older binary addressed a shard by org alone (<data>/<org>/<ns>.db).
This one reads three levels down, so the first boot after the upgrade finds
nothing, creates empty shards beside the full ones, enumerates zero tenants
and never fires a schedule again — silently, with every byte still on disk
one directory up.

store.Upgrade inserts the two sentinel levels uniformly, including the old
empty-org dir (_ -> _/_/_). A rename within one filesystem: no page
rewritten, no re-encryption. Journals move before their database, so a run
that stops half way never leaves a database without the WAL holding its
last commits. Idempotent — a moved shard leaves nothing at its old path —
so a deploy can run it unconditionally ahead of the daemon.

Two refusals, both loud and both non-destructive:

  A master key is set. Pre-upgrade shards are plaintext and moving one does
  not encrypt it; the next boot would wrap a fresh DEK around a file it
  then failed to decrypt. Move first, encrypt second.

  A destination is occupied (ErrOccupied). The only way there is booting
  this binary before the move ran, which creates an EMPTY shard where the
  full one belongs — and anything started after that boot is in the empty
  one. Both files are kept, the other tenants still move, and the operator
  picks which is authoritative.

upgrade and migrate stay separate axes: upgrade moves EVERY shard forward
in time (layout), migrate moves ONE shard across space (nodes).

Also: refuse a socket path over sockaddr_un.sun_path by name. The kernel
answers "bind: invalid argument" and names neither the path nor the limit,
and a socket under a deployment's data directory sits close to it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 20:43:30 -07:00
zeekayandHanzo Dev aae93e1c07 merge: main into the tenancy branch, and move the cron signal to reachability
main's cron regression tests manufactured a failing action by naming an
unregistered namespace. This branch creates a namespace on first use, so
registration stopped being evidence of anything: a cron with a typo in its
namespace now starts a run into a namespace nobody serves, and says nothing.

Report the fault instead of the proxy. A fire is a failure when it does not
reach a worker — either the start errored, or the start succeeded and no
worker is subscribed to (namespace, taskQueue). Same line, same throttle,
same recovery, one reporter (engine.reportFire). It also catches what the
old guard never could: a schedule whose worker died, and a task queue
renamed out from under an entry.

Reachability is asked AFTER the start, because enqueueing prunes
subscriptions whose peer the transport can no longer reach — a worker that
died without unsubscribing is gone from the registry by the time we look.

Anchoring follows the start, not the report: an errored fire stays due and
retries, a started-but-unreached fire re-anchors, because the run exists and
re-firing every tick would spawn a run every 5s.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 20:34:14 -07:00
zeekayandHanzo Dev 1555bd8f5a deps: pin zap v1.2.7
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 19:43:15 -07:00
zeekayandHanzo Dev 0daf1a06ed feat(engine): durable evidence for failing activities and workflows
The sibling fix made the SCHEDULER report. It does not cover the incident.
StartWorkflow SUCCEEDED all 4489 times -- cron-reconcile's actionCount is the
proof -- so the sweeper was healthy and silent by correctness. The fault was
one layer down: cloud's JobWorkflow fires RunJobActivity, which re-reads the
entry's ConfigMap at fire time, and the cloud ServiceAccount had no RBAC to
read ConfigMaps. Every fire's ACTIVITY failed, for 11 days, and all that layer
did about it was e.emit(Event{Kind:"activity.failed"}) into the SSE broker:
ephemeral, no subscriber attached, nothing written anywhere. Six nightly
backups produced nothing, every dashboard read green, and it was found only by
hand-reading the engine's SQLite.

Guarantee provided: DURABLE evidence, plus throttled log lines. Both, not
either. A "fail/<ns>/<fingerprint>" row per failing identity is upserted on
every failure and deleted on the first success. It needs no subscriber and
outlives the process, so ConsecutiveFailures can say 4489 where an in-memory
counter says 1. View.FailureStreaks(ns) hands the rows back worst-first, so
nobody opens SQLite again; the keyspace is bounded by how much is broken now,
not by how often it failed.

Identity is the recurring SHAPE of the work -- (workflowType, activityType,
taskQueue, scheduleId) -- never the run. Every cron fire mints a fresh runId,
so a run-keyed counter would have read "attempt 1 of 10" forty thousand times
and never once said "this has been dead for 11 days". Schedule-started runs now
carry a ScheduleId search attribute (sweeper + TriggerSchedule) so a report can
name the dead cron entry instead of saying "some JobWorkflow is broken"; it
makes ScheduleId a queryable execution filter at the same time.

Three levels, because the distinction is the whole point. WARN "activity
failed" for a failure that will be retried -- normal operation, must not page
anyone. ERROR "activity failing persistently" once the streak has run
unbroken for 15 minutes -- the alertable condition that was invisible.
INFO "activity recovered" when it ends. Same three for a workflow failing with
no activity to blame, which is the hole an activity-only report would leave (a
decider that faults on episode 0 never schedules anything). Persistence is
measured by AGE, not count: a nightly backup reaches a count of 2 in two days
yet is unambiguously broken, while one run burning its 10 default attempts
(~5.5 min of backoff) must not trip it. The persistent transition always
reports whatever the throttle says -- waiting for failure #60 would be the
original bug wearing a different hat.

Throttle reuses the sibling's idiom rather than inventing a second one:
scheduleFailTracker generalises to failTracker (cadence fixed at construction),
sweepFailThrottle to failReportThrottle, and shouldReport is now the single
rule for the whole package. One tracker instance serves schedules and
activities. Two counters exist on purpose and do different jobs: the in-memory
tracker is the throttle authority (a store that is itself failing cannot starve
it into reporting every occurrence, and a restart makes a still-broken activity
re-alert once after a deploy), while the durable row is the evidence and always
supplies the count on the line. Measured: 180 failures produce 4 lines; stub
shouldReport to always-report and it is 180.

Retry and isolation semantics are UNCHANGED -- which branch is taken, when, and
how many times is decided exactly as before, and every emit() stays.
TestFailureReportingPreservesRetrySemantics pins the attempt count, terminal
status, ACTIVITY_TASK_FAILED event count and dispatch count.

Ten tests, all failing without the reporting calls and all on assertions
("rows: []", "records: []" -- the exact silence), covering: durability with no
subscriber, survival across a simulated restart with the count continuing,
naming the schedule end-to-end from a real sweep, the throttle, the
WARN-vs-ERROR distinction, recovery, standalone activities, workflow-only
failures, retry semantics, and per-org isolation of streaks.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 17:22:34 -07:00
zeekayandHanzo Dev 2b86b2ed46 fix(engine): report cron sweep + per-schedule action failures instead of dropping them
The sweeper had two silent paths. runScheduler discarded the sweep error
outright (`_ = e.sweepSchedules()`), so a sweep that failed wholesale --
cron dead for every org at once -- looked exactly like a quiet night. And
inside sweepSchedules a schedule whose StartWorkflow failed hit a bare
`continue`: correct isolation, zero output.

That silence cost 11 days in production. cloud's clients/cron schedules
fire a JobWorkflow whose RunJobActivity re-reads the entry's ConfigMap at
fire time. The cloud ServiceAccount lacked RBAC to read ConfigMaps, so the
activity failed on every single fire. The engine kept firing perfectly
(cron-reconcile reached actionCount 4489) and emitted NOTHING, so every
dashboard read healthy while all six nightly backups produced nothing for
11 days. It was found only by reading the engine's own durable records.

Isolation is unchanged -- one broken schedule still must not stop the
sweep. What changes is that it now says so, through the logger the package
already uses (slog, from EmbedConfig.Logger; slog.Default() when unset).
Everything needed to act goes on the line: org, namespace, scheduleId,
workflowType, taskQueue, consecutiveFailures, error.

Throttled, because a failed fire is deliberately not re-anchored: the entry
stays due and retries on every 5s tick, so unthrottled this is ~17k
identical lines per day per broken schedule, which buries the signal as
thoroughly as silence did. First failure alerts, then one line per 60
sweeps (~5 min, so any 15-minute window still holds 3+ lines). The counter
clears on success -- recovery is logged, and a relapse alerts immediately
-- and on DeleteSchedule. Deliberately NOT "log on error-text change":
StartWorkflow errors can embed the freshly minted random runId, which would
flap every sweep and restore the very flood the throttle prevents.

Tests fail without the fix (all five report `records: []`, the exact
silence) and also catch a naive unthrottled implementation (60 lines vs 2).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:58:48 -07:00
zeekayandHanzo Dev 5af38f7513 refactor(dispatch): carry the principal by value, not by encoding
A dispatch token held its tenant as the canonical string, so delivering
its result had to parse one back and decide what to do when it did not
parse. Falling back to the root tenant there would have written one
tenant's result into another's shard.

The dispatcher runs in-process with the engine, so it holds the
Principal itself. There is nothing to encode, nothing to parse, and no
fallback to get wrong. The encoding stays where it is actually needed:
on a replication frame and a migration job, which leave the process.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:28:29 -07:00
zeekayandHanzo Dev 679ae61163 feat(transport): address the engine and the SDK, so both can use a socket
The engine took a PORT and the SDK an Options.HostPort, so neither end
could use a unix socket for traffic that never leaves the host. The
field name was not the only obstacle: luxfi/zap bound net.Listen("tcp",
":port") and reached a peer with net.DialTimeout("tcp", addr), so a path
was refused at the dialer with "missing port in address" and could not
be bound at all. That is fixed upstream (luxfi/zap Address + Network);
this pins the commit until it is tagged.

EmbedConfig.Address, Embedded.Address, ServeGated(addr) and
client.Options.Address each take ONE address, because a port is a detail
of one transport rather than a thing every listener has. A path binds or
dials a unix socket; anything else is host:port.

TestDialRequiresHostPort became TestDialRequiresAddress: Dial needs an
address, and asserts a socket path is refused for being absent rather
than for being portless. TestE2E_UnixSocket runs a real workflow over a
socket end to end, and TestE2E_UnixSocketRebind proves the socket is
unlinked on stop so a restart binds cleanly.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:27:19 -07:00
zeekayandHanzo Dev b4529923c1 feat(store): principal-addressed shards, created on demand, encrypted at rest
The store addressed a shard by (org, namespace) and only the root org's
`default` namespace existed, so anything else had to be declared before
it could be used and there was no way to isolate a project or a user.
Shards also had no way to be keyed, so tasks was the one Hanzo store
writing tenant state in the clear.

Both are the same missing value, so both are one change.

Principal is the tenant that owns a shard: an org, optionally narrowed
to a project and a user. It serves the two places tenancy is decided, so
they cannot disagree — the shard's directory
(<data>/<org>/<project>/<user>/<ns>.db, each unset leg written "_") and
the key its DEK is wrapped under. The fixed-depth encoding is injective,
so a project and a user of the same name are different tenants, and the
KEK chain master -> org -> project -> user gives each of them a key
contained in the one it narrows.

Namespaces come into existence on first use (engine.namespace), the way
their shards already did. ValidName is the one rule every name that
becomes a path segment passes through, so a namespace can no longer
escape or alias a directory.

EmbedConfig.MasterKey opens every shard encrypted: each file carries a
DEK of its own, wrapped for its principal and bound to a random file id
in a sidecar beside it, so rotating the master rewraps sidecars and
never rewrites ciphertext, and moving the data directory is harmless.
A keyed shard is ciphertext on every build — hanzoai/sqlite v0.4.0 uses
the live libsqlcipher codec when one is linked and its pure-Go SQLCipher
envelope when one is not — so there is nothing here to branch on. On the
envelope a shard is sealed at checkpoint/close rather than per commit,
which is what Shard.Checkpoint and the manager's sweep bound.

replication.Frame and migration.Job carry the canonical principal string
instead of an org, so a frame lands in the directory its principal names.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-28 16:16:39 -07:00
zeekayandHanzo Dev 186ecae3fb fix(docker): golang 1.26.4 -> 1.26.5, the version go.mod already requires
go.mod declares `go 1.26.5` while the builder pinned golang:1.26.4. The golang
images set GOTOOLCHAIN=local, so the base can never fetch a newer toolchain to
satisfy the directive and the build dies immediately:

    go: go.mod requires go >= 1.26.5 (running go 1.26.4; GOTOOLCHAIN=local)

A release build that fails in under a second did not fail to compile — it
failed to acquire a toolchain.

Found by sweeping every hanzoai repo with a go.mod against its Dockerfile base:
25 declare go >= 1.26.5, and 16 pin an explicit 1.26.4 that cannot satisfy it.
Repos on a floating `1.26` / `1.26-alpine` are already fine — both now resolve
to 1.26.5 (verified by digest: golang:1.26-alpine and golang:1.26.5-alpine are
the same sha256:0178a641).

Patch bump only, image variant preserved, and the target tag verified to exist
before the change.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 19:12:34 -07:00
zeekayandHanzo Dev 2de84d773e chore(go): bump go directive to 1.26.5
Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 16:17:27 -07:00
zeekay ca47c5af17 ci: drop the Gitea mirror-sync nudge
Superseded: the Hanzo GitHub App pushes a webhook, so the forge tracks GitHub
without a per-repo workflow. This file called git.hanzo.ai/api/v1/.../mirror-sync
— a Gitea API for a system we no longer drive — and would sit inert in every repo.

One mechanism, in one place, instead of ~350 copies of a cron.
2026-07-27 10:44:53 -07:00
zeekayandHanzo Dev 914ba48887 ci: run cicd on the forge, leave sync.yml on the mirror
git.hanzo.ai is canonical and reads .hanzo/workflows, so cicd.yml moves there
by changing directory and nothing else — same GitHub Actions syntax, same
runs-on, byte-identical file. .github/workflows keeps exactly one workflow,
sync.yml, which carries pushed refs to the forge.

hanzo.yml still holds all the config, so the build and test lanes are
unchanged; it just points at the new path. LLM.md documents the chain and
drops a stale reference to build-and-publish.yml, a workflow this repo no
longer has.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-27 08:35:00 -07:00
zeekay fbf2191dd6 docs(auth): canonical /v1/iam/.well-known/jwks in the JWKS references
The bare /.well-known/jwks form is only answered by the hanzo.id-worker
shim, which is being retired; IAM's discovery document advertises
/v1/iam/.well-known/jwks on both the public host and in-cluster.
2026-07-25 15:12:32 -07:00
zeekay 44983433d9 feat(embed): View.StartActivity + View.DescribeActivity — org-scoped in-binary activity seam
A host subsystem (cloud functions fleet executor) enqueues standalone
activities on an org queue and polls them without an HTTP loopback hop,
mirroring the schedule passthroughs already on View.
2026-07-22 23:32:04 -07:00
zeekay ce99746250 docs(LLM): note the terminal-activity GC gap (act/<ns>/ retention unenforced)
Read is bounded now (cloud fleet queue recency-sorts + caps terminal + walks all
pages via ActivitiesPageForOrg v1.51.3), but storage isn't: terminal standalone
activities have no retention sweeper. Queued as v1.51.4 fast-follow. Surfaced in the
hanzoai/cloud per-GPU-queue review; issues are disabled on this repo so tracked here.
2026-07-21 12:48:46 -07:00
zeekay c2717c58cc merge: org-scoped Cancel/ActivitiesPage (v1.51.2, v1.51.3) into main
Brings CancelActivityForOrg + ActivitiesPageForOrg onto main and makes the v1.51.2
and v1.51.3 release tags reachable from main's history (they were cut off v1.51.1 as
a detached patch line so cloud's pinned tree stayed valid). Additive methods, no
behavior change to the engine.
2026-07-21 12:32:07 -07:00
zeekay 74a93f0146 feat(embed): ActivitiesPageForOrg — paginated org-scoped read (walk past the 100-row cap)
ActivitiesForOrg returns only the first hash-ordered 100 rows; a busy org past ~100
lifetime activities then sees a random subset — live jobs hidden, online workers
dropped. ActivitiesPageForOrg exposes the cursor ListActivities already carries so an
in-process host can walk a namespace to completion. Additive; org-scoped tenancy is
the caller's to enforce. (v1.51.3 = v1.51.1 + CancelActivityForOrg + this.)
2026-07-21 12:31:44 -07:00
zeekay 5e891791df feat(embed): CancelActivityForOrg — org-scoped cancel mutator for in-process hosts
Mirrors ActivitiesForOrg's org-scoped read with a matching mutator so a host
binary (cloud's clients/visor fleet) can cancel a queued/running gpu-jobs
activity it just listed, without a second HTTP hop into its own tasks surface.
Tenancy is the caller's to enforce (validated X-Org-Id). Enables the cloud
POST /v1/fleet/jobs/:id/cancel endpoint.
2026-07-21 11:03:11 -07:00
zeekay 5e0d831d98 merge(fork-hygiene-notice): land ZAP-only tasks transport + branding/provenance sweep 2026-07-19 19:54:49 -07:00
zeekay 30171060e1 refactor(tasks): drop HTTP transport, ZAP or local only
The client now has one durable path (ZAP) and a local goroutine-timer
fallback for dev. Removes the tasksURL/httpClient submit path and the
duplicated ZAP opcode/field-offset constants; New(zapAddr, handler) loses
its tasksURL argument. embed.go decodes a schedule's interval spec from the
wire alongside cron. Tests boot an embedded Tasks server on a free ZAP port
and assert Now()/Add() persist workflows and schedule specs over ZAP.
go build + go test ./pkg/tasks/ green.
2026-07-19 19:53:59 -07:00
zeekay 00b478a364 chore(notice): pin Temporal provenance and deviations; sweep product branding 2026-07-19 19:53:59 -07:00
zeekay 79f01664ab fix(replication): FrameKey as a free function — can't method a non-local type
The quasar-driver package move left FrameKey() defined as a method on the
imported replication.Frame → 'cannot define new methods on non-local type'
broke the build. Make it a free function (same shape as frameID); no callers
change (it had none).
2026-07-18 09:07:04 -07:00
zeekay 9c1103af3d ci: pin hanzoai/ci@v1 (canonical stable alias) 2026-07-18 08:51:11 -07:00
zeekay 706aeb7411 refactor(replication): move quasar driver to its own package (base sheds consensus)
hanzoai/base transitively pulled github.com/luxfi/consensus solely through
pkg/tasks → replication (quasar.go, the only consensus importer). That made
base — and every base consumer — vulnerable to the recurring luxfi/consensus
force-moved-tag / vanished-geth supply-chain rot, for a driver base never uses.

Make Quasar replication optional by isolating it:
- Add Kind() + a unified Stats(accepted,rejected,timeouts) to the Replicator
  interface so embed.go introspects drivers through the interface, never a
  concrete type.
- Move quasar.go (+ its test) into a new pkg/tasks/replication/quasar package
  that imports the interface package; the consensus dependency now lives ONLY
  there. Only cmd/tasksd imports it.
- pkg/tasks → replication now has ZERO consensus in its dep graph
  (`go list -deps ./pkg/tasks | grep consensus` = 0), so base sheds it via Go
  1.17+ module-graph pruning.

Also unbreak tasks' own consensus: v1.22.85 → v1.36.3 (geth v1.16.73 was a
vanished revision; v1.36.3 floors the valid unified luxfi stack). Non-quasar
packages build + test green CGO-off; the quasar package builds in CI (its
consensus→secp256k1 CGO can't compile in this sandbox — environmental).
2026-07-17 16:36:18 -07:00
c1300f3aeb fix(store): remove dead bootNS set that raced → concurrent map writes crash (#18)
store.bootNS was a write-only set (never read) guarded by a value-typed mu.
withOrg() shares the map by reference but COPIES the mutex, so N org-scoped
store views each locked a DIFFERENT mutex while writing the ONE shared map —
zero mutual exclusion. Under concurrent cross-org traffic the runtime fataled
with 'concurrent map writes' (store.go:100, via shardFor on every put/get),
crashing the whole embedded tasksd — i.e. the entire cloud process / api.hanzo.ai.

Fix is a decomplection: the set was dead state, so delete it (and its now-unused
mu + sync import + the per-op lock dance in shardFor). No map, no race. Net -11
lines in store.go. Adds TestStore_ConcurrentCrossOrgNoRace which reproduces the
exact crash on the old code (fatal → FAIL) and passes on the fix (verified under
-race).

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-16 19:30:06 -07:00
477c7baa6e feat(auth): org/project/user-native identity — X-Project-Id minted from the validated project claim (#16)
The IAM identity model is org/project/user; tasks carried only org+user.
IAMClaims gains `project`; RequireIdentity mints X-Project-Id (strip-list
⊇ mint-list unchanged — the header is stripped on every inbound request
and set only from a validated JWT); WithIdentity gains the project param
(in-process embedders pass their validated project through); ProjectID(ctx)
accessor. Convention: a project maps onto a tasks NAMESPACE inside the
org's shard.


Co-authored-by: hanzo-dev <[email protected]>
2026-07-12 00:00:10 -07:00
24787131fb fix(docker): git + buildkit-secret auth for the private hanzoai/sqlite module (#15)
The canonical CI image build failed at go mod download: the alpine build
stage has no git and no auth for the private module. Same dual-mount
(gh_token / GIT_AUTH_TOKEN) pattern as hanzoai/iam's Dockerfile; public
modules stay on proxy+sumdb (retag-proof).


Co-authored-by: hanzo-dev <[email protected]>
2026-07-11 23:17:22 -07:00
b64d691594 fix(engine): cron sweeper fires on the sharded store + org-scoped View (#14)
* fix(engine): make the cron sweeper actually fire on the sharded store + org-scoped View

The 5s sweeper called store.list("sc/") — a cross-namespace, cross-org
scan the per-(org,ns) shard router refuses ("missing namespace in
prefix"). runScheduler discarded the error, so durable schedules NEVER
fired on the sharded store: every CreateSchedule (automations cron,
base durable cron, tasksd schedules) registered and then sat idle.

- store.listAllOrgs + store.Manager.ListOrgs: enumerate every org's
  shards for root sweeps.
- sweepSchedules: two-phase (collect due → fire) so starting a workflow
  never nests a query inside the shard List iteration (single-conn
  SQLite deadlock); fires AT MOST ONE action per schedule per sweep and
  re-anchors at now — recovering after downtime runs the schedule, it
  does not storm the missed backlog; per-schedule error isolation.
- nextScheduleFire honors Spec.Interval (what base's durable client
  writes), not only CronString.
- Embedded.View(org): exported in-process, org-scoped control-plane
  handle (RegisterNamespace/CRUD/Trigger schedules) for host binaries
  embedding the engine — cloud's platform cron mounts on this.

Tests: sweep fires (root + org shard, no cross-shard leak), backlog
clamped to 1, interval specs fire, broken entry doesn't poison the
sweep, View CRUD e2e. go test -race ./pkg/tasks/... green.


* ci: replace legacy Temporal workflow suite with canonical hanzo.yml + cicd.yml

19 upstream-era workflows (sharded run-tests matrices, promote-* image
lanes, flaky-test reporting, version-info triggers) targeted the pre-rip
fork layout and have been red on every run since the ZAP-native rewrite
(yq-less runners, deleted directories). One way: root hanzo.yml declares
the image + the -race test gate; cicd.yml imports hanzoai/ci build.yml on
the arc pool.


* ci: scope test gate to the packages that exist post-rip


* feat(embed): View.ListWorkflows — hosts observe their schedules' runs


---------

Co-authored-by: hanzo-dev <[email protected]>
2026-07-11 22:49:35 -07:00
zeekay 86399f74ed ci: route linux/amd64 jobs to hanzo-build-linux-amd64 ARC scale set 2026-07-10 21:52:14 -07:00
6f6a6460ab chore(tasks): rip all gRPC + protobuf — ZAP-native only (HIP-0114) (#12)
Complete the documented 2026-04-26 native-ZAP migration whose deletion
was left incomplete. The engine (cmd/tasksd), SDK (pkg/sdk) and
in-process server (pkg/tasks) are already 100% ZAP-native with zero
real go.temporal.io / google.golang.org/grpc / protobuf imports; the
only residual gRPC+Temporal footprint was dead porting scaffolding:

- rm proto/ — 55 vendored Temporal .proto (4 gRPC service defs +
  message shapes), zero generated .pb.go, zero Go references.
- rm cmd/tools/ — 4 Temporal-porting tools (genrpcwrappers,
  genroutingkeyextractor, getproto, check-dependencies); the only
  files importing google.golang.org/grpc + go.temporal.io/{api,server}.
- go mod tidy — drops go.temporal.io/api, go.temporal.io/server,
  google.golang.org/grpc, grpc-gateway entirely (zero grpc/protobuf
  direct or transitive in go.mod).
- CI: remove orphaned proto jobs (linters.yml lint-protos/lint-api,
  check-release-dependencies.yml) that ran deleted tools / missing
  make targets.
- LLM.md: scrub stale gRPC transport claims -> ZAP :9999 / HTTP :7243.

Transport is luxfi/zap on :9999. go build ./... , go vet, go test all green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-07 16:42:41 -07:00
85159baf8c fix(tasks): self-healing task delivery — prune leaked dead-peer subscriptions (#11)
luxfi/zap exposes no disconnect hook, so when a worker dies its dispatcher
subscription leaks. Round-robin then keeps picking the dead peer and the
server-push Send is silently dropped (the task is lost, never retried) — a
social orchestrator that restarts would stall on its 'main'/provider queues.

Make delivery self-healing: on a failed Send, prune the dead peer's subscription
and redeliver to the next live subscriber; queue only when none remain.
drainLocked now drains the whole backlog to a fresh subscriber rather than one
task per Subscribe.

Adds TestDispatcher_PrunesDeadPeerOnSendFailure (dead peer pruned, task reaches
the live peer, second enqueue skips the dead peer). Full pkg/tasks suite green.

Motivated by the social→Hanzo Tasks migration: verified live that a durable
workflow runs to COMPLETED over the gated cloud:9999 listener with a real
hanzo-social IAM token; delivery only stalled after leaked subscriptions
accumulated from worker restarts.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-04 23:09:29 -07:00
zeekay 3156793826 fix(sdk): accept ZAP wire v2 (luxfi/zap v1.2.0) + drop-in gaps; engine: CAN-chain describe
The cloud embedded engine links luxfi/zap v1.2.0 via MVS, whose NewBuilder stamps
wire version 2; the TS SDK only accepted version 1 -> 'unsupported version 2'
against cloud's gated :9999. The generic object encoding is byte-identical across
v1/v2 (only the platformvm TxKind schema differs, which this SDK never uses) and
v1.2.0's Parse accepts v1, so: keep emitting v1 (both engines accept it), accept
BOTH 1 and 2 on read. Verified live against cloud v1.786.102.

Also (drop-in compat, from the social migration):
- export TokenProvider from the package root.
- proxyActivities<A>: open the generic so proxyActivities<SomeActivityClass>()
  type-checks; ProxyActivityOptions accepts cancellationType (no-op).
- engine.moreCurrentRun: a CONTINUED_AS_NEW run ranks below any other run of the
  same workflowId, so the completed tail of a continue-as-new chain resolves over
  its closed predecessor on a same-second StartTime (DescribeWorkflow by id).
2026-07-04 22:11:10 -07:00
zeekayandGitHub 52433f1357 Merge pull request #9 from hanzoai/feat/durable-social-primitives
feat(engine): durable social primitives — signals, continueAsNew, startChild, search attrs
2026-07-04 21:41:26 -07:00
zeekay 71b3c30d73 feat(sdk): IAM bearer auth over ZAP (auth_token) for the gated frontend
The gated engine (cloud ServeGated :9999) requires an auth_token on every
JSON-body RPC; the TS SDK had no way to send one. Add a TokenProvider that
rides client lifecycle + worker Subscribe as auth_token (mirrors the Go SDK's
Options.Token), injected at the ZAP transport for JSON bodies only — worker
Respond/Heartbeat field-object frames are HMAC-authenticated and untouched.

Threaded through Connection/TasksClient/Worker options. Proven: unit test
(auth_token rides JSON RPCs, absent without a source) + gated e2e vs a real
RequireIdentity tasksd with a local RS256 JWKS (anonymous -> 401; IAM-bearer
client+worker run a durable workflow to COMPLETED with org-scoped namespace).
2026-07-04 21:39:26 -07:00
zeekay a60626ae9e feat(engine): durable social primitives — signals, continueAsNew, startChild, search attrs, conflict policy
The social-orchestrator migration off upstream Temporal onto the embedded
Hanzo Tasks engine needs five workflow primitives its digest/sendEmail/post
workflows depend on. Implemented server-side (event-sourced, replay-safe) plus
the @hanzoai/tasks TS SDK (the worker social runs):

- Signal → running workflow: engine.signalWorkflow now re-dispatches a workflow
  task after appending WORKFLOW_EXECUTION_SIGNALED, so the stateless worker
  replays the extended history and fires the handler (digest/sendEmail are
  entirely signal-driven). TS decider read the wrong history attr key
  ("signal" vs "signalName") — fixed.
- continueAsNew (kind=4): closes the run CONTINUED_AS_NEW + starts a successor
  under the same workflowId carrying input/search-attrs/memo. TS continueAsNew
  emits the command instead of throwing ContinueAsNewNotSupported.
- startChild (kind=5): detached (ABANDON) child, seq-keyed + idempotent; retires
  the 0x006D 501 for the command path. TS startChild/executeChild added.
- Typed search attributes: carried on StartWorkflow/SignalWithStart wire, stored
  on the execution, visibility-queryable (already read by fieldValue). TS adds
  TypedSearchAttributes/defineSearchAttributeKey/SearchAttributeType.
- workflowIdConflictPolicy USE_EXISTING/TERMINATE_EXISTING/FAIL.
- ActivityFailure wraps ApplicationFailure (with .type) so workflow error
  matching (err.cause.type === 'refresh_token') works.

Also fixes a pre-existing wire defect: the server registered
SignalWithStartWorkflow at 0x0069 while every client sends 0x0066 (schema +
Go/TS SDK) — signalWithStart 404'd against the real engine. Swapped with the
HTTP-only GetWorkflowHistory (no ZAP client).

DescribeWorkflow(workflowId, "") now resolves the OPEN run (Temporal's current
execution) so a continueAsNew successor is the one signalled/described.

Tests: engine unit (search attrs, conflict policy, continueAsNew, startChild)
+ TS e2e vs real tasksd (signals-across-continueAsNew, startChild, search attrs
run to COMPLETED). go test -race ./pkg/... green; TS vitest green.
2026-07-04 21:30:09 -07:00
5a5cf590de feat(engine): gated cluster ZAP listener + identity over ZAP + org-scoped completion (#8)
Enables consolidating the standalone tasksd onto an in-process embedded engine
(cloud) by exposing it cluster-wide under mandatory identity gating, and by
fixing two gaps that made identity-gated ZAP durable execution impossible.

Embedded.ServeGated(ctx, port, *auth.Validator): starts a SECOND ZAP listener
that exposes the SAME engine to out-of-process callers with RequireIdentity --
every request must carry an auth_token that validates against IAM, org-scoped to
the token owner. The loopback listener from Embed is unchanged (in-process,
trusted). Server-push is routed to the listener holding the worker's
subscription, so gated and loopback workers both receive delivery. A nil
validator is refused (never expose durable execution ungated).

SDK: Options.Token TokenSource attaches auth_token to every JSON-body RPC
(client lifecycle + worker Subscribe) at the transport; binary respond frames
stay task_token-gated. This is the missing client half -- the frontend already
read req["auth_token"], but no SDK ever set it, so a RequireIdentity frontend
was unreachable (every caller 401'd). StaticToken helper for fixed bearers;
client_credentials callers return a fresh token per call so long-lived workers
never present an expired identity.

Org-scoped completion: the respond handlers ran on rootEn (unscoped) while
org-scoped runs live in an org-prefixed store partition, so an org-scoped
workflow was accepted (RUNNING) but never advanced. Thread orgID through the
dispatcher's pending tasks and apply completion via en.WithOrg(orgID). orgID==""
(loopback/unscoped) makes WithOrg a no-op -- the in-process path is unchanged.

RegisterNamespace over ZAP: accept the SDK's flat wire ({"name",...}); the nested
{"namespaceInfo":{...}} unmarshal never matched what the client sends, so an
org-scoped caller could not register the namespace ExecuteWorkflow requires.

Test: TestE2E_ServeGated_DurableWorkflow_RequiresIdentity drives a real durable
workflow (schedules an activity, returns its result) to COMPLETED over the gated
listener with a JWKS-signed token, and asserts an unauthenticated caller is
refused. Full suite green.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-04 20:41:30 -07:00
25f19a5a30 feat(sdk): TypeScript SDK (@hanzoai/tasks) — durable execution over ZAP (#7)
Native TS client + worker over the Hanzo Tasks ZAP wire, byte-compatible with pkg/sdk (Go) and luxfi/zap v0.2.0. Drop-in for @temporalio/* + nestjs-temporal-core so the social-orchestrator migration is a dependency swap.

Includes: byte-exact ZAP message codec + TCP node (handshake, reqID correlation, Send-push dispatch); full client (start/signal/signalWithStart/query/describe/cancel/terminate/list, namespaces, health); activity worker (subscribe/dispatch/heartbeat/respond); event-sourced workflow replay decider (proxyActivities, durable activity-backed timers, condition, defineSignal/setHandler); temporal failure envelope serde; @temporalio compat (Connection/Client/NativeConnection/Worker/ApplicationFailure).

Tests: 25 vitest specs green (byte-layout golden, decider unit, full durable loop through a faithful ZAP mock) + a live integration suite that passes against a running tasksd. tsc --noEmit clean.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-04 13:39:01 -07:00
zeekay a9ac37abb9 feat(tasks): outbound worker claim + lease reaper for standalone activities
ClaimNextActivity is the NAT-safe pull primitive an outbound worker
(hanzo gpu connect) polls: it atomically claims the oldest SCHEDULED
activity in a namespace/taskQueue for a worker identity, transitioning it
STARTED under a lease (per-(org,ns) claim lock ⇒ no double-claim). Expired
leases are reaped on the claim hot path (self-healing when a worker dies)
and by the background scheduler sweep — requeued (attempt++) or FAILED once
MaximumAttempts is spent. Heartbeat refreshes the lease; unclaimed presence
records (the fleet registry) carry no lease and are never reaped.

Surface: POST /v1/tasks/namespaces/{ns}/activities/claim (200 claimed |
204 empty) and Embedded.ActivitiesForOrg(org, ns) — the thin org-scoped read
the cloud fleet surface uses.

Tests (-race clean): claim transition+lease, taskQueue filter, oldest-first,
reap requeue+attempt-bump, exhausted-attempts fail, heartbeat-keeps-lease,
presence-untouched, and the HTTP 200/204 claim route.
2026-07-04 12:24:40 -07:00
zeekay 48beecff40 feat(tasks): embeddable identity + single sqlite driver for in-proc mount
Enables mounting the Tasks server natively inside the unified hanzoai/cloud
binary (HIP-0106) without a JWT re-validation hop or a duplicate sqlite driver.

- auth.WithIdentity injects an already-validated identity (org/user/email)
  into the handler context — the in-process twin of RequireIdentity's mint
  step, for an embedder that terminates the IAM trust boundary at its gateway
  before the request reaches Tasks.
- store opens through github.com/hanzoai/sqlite (the one Hanzo sqlite driver)
  instead of blank-importing modernc directly, so a Tasks store embedded in
  the cloud binary shares the single "sqlite" driver registration rather than
  double-registering it and panicking at init. WAL/pragmas move to explicit
  schemaSQL so they apply on both cgo and !cgo backends.
2026-07-03 15:49:58 -07:00
zeekay d95d6b170b test(tasks): Phase-2a durable core — exactly-once, retry+backoff, crash-recovery
White-box (pkg/tasks/durable_test.go):
- exactly-once activity dispatch keyed by (run,seq): one record/event/dispatch
  when the same seq is scheduled twice, plus a concurrent -race variant.
- crash-recovery invariants: a fresh engine over the same store re-dispatches
  only the non-terminal activity (the COMPLETED seq is never re-run) and
  re-enqueues a workflow task.

Full-stack (pkg/tasks/durable_e2e_test.go, real Embed+client+worker):
- activity retry+backoff: fails twice then succeeds; asserts 3 attempts,
  COMPLETED, and growing backoff gaps.
- retry exhaustion: MaximumAttempts=3 always-fail → workflow FAILED after 3.
- crash-recovery: activity in-flight on worker A, restart onto the same store,
  worker B completes it exactly once → workflow COMPLETED (no double execution).

go test -race ./pkg/tasks/... ./pkg/sdk/... green.
2026-07-02 18:22:52 -07:00
zeekay 2bf2702045 feat(tasks): event-sourced durable activity core (Phase-2a)
Replace the coroutine-push activity path with deterministic, history-backed
replay. One way: the old push-result mechanism is removed.

Server (pkg/tasks):
- durable.go: seq-keyed activity records (wfact/ns/wf/run/seq) — the
  exactly-once anchor. applyScheduleActivity is idempotent per (run,seq);
  completeWorkflowActivity records the terminal outcome and schedules a new
  workflow task so the worker replays and advances. Per-run keyedMutex
  serializes advancing a run. Server-side retry+backoff per RetryPolicy
  (temporal.RetryPolicy, finite default bound). Recover() rebuilds in-flight
  dispatch from the store at boot (called from Embed).
- workflow tasks now carry the run's full event-sourced history.
- dispatch.go: ScheduleActivity/CompleteActivityTask(push) -> DispatchActivity
  (seq-bound token) + ResolveActivityToken. workflowPeer/pendingActivity and
  OpcodeDeliverActivityResult retired.
- respondWorkflowHandler applies ScheduleActivity{seq} commands under the run
  lock; respondActivity* resolve the token and advance the run.

Worker (pkg/sdk/worker):
- workerEnv is now a replay decider: ExecuteActivity resolves from history by
  seq (recorded result -> no re-dispatch; else emit ScheduleActivity{seq} and
  end the episode via a blockedFuture). Stateless between episodes.
- removed OnActivityResult/pendingActivities push machinery.

Client (pkg/sdk/client): drop OnActivityResult + ScheduleActivity from
WorkerTransport (dead in the replay model).

Tests: e2e (exactly-once, real workers) green; new worker replay determinism
tests (unresolved->schedule+block, resolved->recorded result, 2-activity
determinism). Full 'go test -race ./pkg/tasks/... ./pkg/sdk/...' green.
2026-07-02 18:15:37 -07:00
zeekay 73318cb78a docs(engine): authoritative Phase-2 event-sourced durable engine design
Correct the stale 'handlers return 501' record: the native engine is
Phase-1-complete and green. The real gap is deterministic replay /
durability. Specify the event-sourced model (history as source of truth,
workflow-task decision episodes, seq-keyed exactly-once activity
dispatch, server-side retry+backoff, single-replica crash-recovery,
multi-replica dispatch lease) and the 2a/2b/2c phasing. Flag the
origin/main temporal re-merge regression as a coordination hazard.
2026-07-02 17:34:54 -07:00
zeekay 6cdacd2c21 chore: OSS attribution — Temporal (MIT) LICENSE + NOTICE 2026-07-02 12:46:50 -07:00
zeekay ea5a5eb6fd Merge branch 'bump/luxdb-v1.19.3'
# Conflicts:
#	go.mod
#	go.sum
2026-07-01 06:32:45 -07:00
zeekayandHanzo Dev cc7a80f1cd deps: pin go.temporal.io/server v1.32.0-157.0 (fork base); finish temporal-fork rip; ui/dist embed placeholder
Co-authored-by: Hanzo Dev <[email protected]>
2026-06-30 16:10:51 -07:00
zeekay 7cb60d259c docs(brand): add hero banner 2026-06-28 20:09:59 -07:00
zeekay 5c6e584ab6 chore(brand): dynamic hero banner 2026-06-28 20:09:58 -07:00
zeekayandGitHub 9147b54e5c chore: bump luxfi/database v1.19.3 (#6)
Co-authored-by: zeekay <[email protected]>
2026-06-25 15:20:33 -07:00
zeekay 4fcc600c64 chore: bump luxfi/database v1.19.3 2026-06-25 13:10:32 -07:00
zeekay ec931d13dd build(deps): drop dead zap-proto/go dependency
The require github.com/zap-proto/go v1.0.0-rc1 had zero imports in the
module (no .go file references it). Removed from go.mod and go.sum.
2026-06-21 01:26:59 -07:00
0fcad808f4 ci: run on self-hosted ARC pool (hanzo-build-linux-amd64/deploy), not GitHub-hosted (#4)
Co-authored-by: zeekay <[email protected]>
2026-06-19 20:39:24 -07:00
zeekay ed523e66c7 ci: route to canonical native arcd labels [self-hosted, linux, <arch>]
Replaces non-canonical scale-set / org-prefixed labels with the
existing labels every arcd host registers with. Matches evo for
amd64 and spark for arm64. No new labels added.
2026-06-10 20:14:34 -07:00
zeekay 887d1778ba deps: prometheus/client_golang → luxfi/metric
Mechanical migration following the beego v2.3.8 fork precedent
(bc7b075). Same exposition surface, zero prometheus/client_golang
in the dep graph.
2026-06-10 18:37:12 -07:00
zeekay 154ed070d5 chore: update 2026-06-10 18:37:12 -07:00
zeekay 8473a2c8ca deps: bump Go to 1.26.4 across go.mod, Dockerfiles, GH Actions
Workspace-wide sync. luxfi/node already shipped on 1.26.4 in v1.30.6
(commit 121aca1fa9); this is the cross-repo catch-up.
2026-06-07 12:12:47 -07:00
zeekay 279dc75477 deps: bump github.com/zap-proto/go to v1.0.0-rc1
Canonical bootstrap (commit f123708 series). Replaces the v0.2.x
prototype lineage with the v1.x runtime.
2026-06-07 11:29:26 -07:00
zeekay 6b89892286 merge: upstream/main (preserve Hanzo brand, 494 commits)
# Conflicts:
#	.github/workflows/build-and-publish.yml
#	AGENTS.md
#	AGENTS.md~upstream_main
#	api/adminservice/v1/request_response.go-helpers.pb.go
#	api/adminservice/v1/request_response.pb.go
#	api/adminservice/v1/service.pb.go
#	api/adminservice/v1/service_grpc.pb.go
#	api/adminservicemock/v1/service_grpc.pb.mock.go
#	api/archiver/v1/message.pb.go
#	api/batch/v1/request_response.pb.go
#	api/checksum/v1/message.pb.go
#	api/deployment/v1/message.go-helpers.pb.go
#	api/deployment/v1/message.pb.go
#	api/enums/v1/replication.go-helpers.pb.go
#	api/enums/v1/replication.pb.go
#	api/enums/v1/task.go-helpers.pb.go
#	api/enums/v1/task.pb.go
#	api/errordetails/v1/message.go-helpers.pb.go
#	api/errordetails/v1/message.pb.go
#	api/historyservice/v1/request_response.go-helpers.pb.go
#	api/historyservice/v1/request_response.pb.go
#	api/historyservice/v1/service.pb.go
#	api/historyservice/v1/service_grpc.pb.go
#	api/historyservicemock/v1/service_grpc.pb.mock.go
#	api/matchingservice/v1/request_response.pb.go
#	api/matchingservice/v1/service.pb.go
#	api/persistence/v1/chasm.pb.go
#	api/persistence/v1/executions.go-helpers.pb.go
#	api/persistence/v1/executions.pb.go
#	api/persistence/v1/workflow_mutable_state.pb.go
#	api/replication/v1/message.pb.go
#	api/routing/v1/extension.pb.go
#	api/schedule/v1/message.pb.go
#	api/taskqueue/v1/message.go-helpers.pb.go
#	api/taskqueue/v1/message.pb.go
#	chasm/component.go
#	chasm/component_mock.go
#	chasm/context.go
#	chasm/context_mock.go
#	chasm/engine.go
#	chasm/engine_mock.go
#	chasm/field.go
#	chasm/field_test.go
#	chasm/lib/activity/activity.go
#	chasm/lib/activity/activity_tasks.go
#	chasm/lib/activity/activity_test.go
#	chasm/lib/activity/config.go
#	chasm/lib/activity/frontend.go
#	chasm/lib/activity/fx.go
#	chasm/lib/activity/gen/activitypb/v1/activity_state.pb.go
#	chasm/lib/activity/gen/activitypb/v1/request_response.go-helpers.pb.go
#	chasm/lib/activity/gen/activitypb/v1/request_response.pb.go
#	chasm/lib/activity/gen/activitypb/v1/service.pb.go
#	chasm/lib/activity/gen/activitypb/v1/service_client.pb.go
#	chasm/lib/activity/gen/activitypb/v1/service_grpc.pb.go
#	chasm/lib/activity/handler.go
#	chasm/lib/activity/library.go
#	chasm/lib/activity/proto/v1/activity_state.proto
#	chasm/lib/activity/proto/v1/request_response.proto
#	chasm/lib/activity/proto/v1/service.proto
#	chasm/lib/activity/proto/v1/tasks.proto
#	chasm/lib/activity/statemachine.go
#	chasm/lib/activity/statemachine_test.go
#	chasm/lib/activity/validator.go
#	chasm/lib/activity/validator_test.go
#	chasm/lib/buf.yaml
#	chasm/lib/callback/component.go
#	chasm/lib/callback/config.go
#	chasm/lib/callback/fx.go
#	chasm/lib/callback/invocable_internal.go
#	chasm/lib/callback/invocable_outbound.go
#	chasm/lib/callback/library.go
#	chasm/lib/callback/proto/v1/message.proto
#	chasm/lib/callback/proto/v1/tasks.proto
#	chasm/lib/callback/request.go
#	chasm/lib/callback/request_test.go
#	chasm/lib/callback/tasks.go
#	chasm/lib/callback/tasks_test.go
#	chasm/lib/nexusoperation/cancellation.go
#	chasm/lib/nexusoperation/cancellation_statemachine.go
#	chasm/lib/nexusoperation/config.go
#	chasm/lib/nexusoperation/fx.go
#	chasm/lib/nexusoperation/gen/nexusoperationpb/v1/operation.go-helpers.pb.go
#	chasm/lib/nexusoperation/gen/nexusoperationpb/v1/operation.pb.go
#	chasm/lib/nexusoperation/gen/nexusoperationpb/v1/tasks.go-helpers.pb.go
#	chasm/lib/nexusoperation/gen/nexusoperationpb/v1/tasks.pb.go
#	chasm/lib/nexusoperation/library.go
#	chasm/lib/nexusoperation/metrics.go
#	chasm/lib/nexusoperation/operation.go
#	chasm/lib/nexusoperation/operation_statemachine.go
#	chasm/lib/nexusoperation/proto/v1/operation.proto
#	chasm/lib/nexusoperation/proto/v1/tasks.proto
#	chasm/lib/scheduler/backfiller.go
#	chasm/lib/scheduler/backfiller_tasks.go
#	chasm/lib/scheduler/backfiller_tasks_test.go
#	chasm/lib/scheduler/config.go
#	chasm/lib/scheduler/export_test.go
#	chasm/lib/scheduler/fx.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/message.go-helpers.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/message.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/request_response.go-helpers.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/request_response.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/service.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/service_client.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/service_grpc.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/tasks.go-helpers.pb.go
#	chasm/lib/scheduler/gen/schedulerpb/v1/tasks.pb.go
#	chasm/lib/scheduler/generator.go
#	chasm/lib/scheduler/generator_tasks.go
#	chasm/lib/scheduler/generator_tasks_test.go
#	chasm/lib/scheduler/handler.go
#	chasm/lib/scheduler/handler_test.go
#	chasm/lib/scheduler/helper_test.go
#	chasm/lib/scheduler/invoker.go
#	chasm/lib/scheduler/invoker_execute_task_test.go
#	chasm/lib/scheduler/invoker_process_buffer_task_test.go
#	chasm/lib/scheduler/invoker_tasks.go
#	chasm/lib/scheduler/library.go
#	chasm/lib/scheduler/migration/migration.go
#	chasm/lib/scheduler/migration/migration_test.go
#	chasm/lib/scheduler/proto/v1/message.proto
#	chasm/lib/scheduler/proto/v1/request_response.proto
#	chasm/lib/scheduler/proto/v1/service.proto
#	chasm/lib/scheduler/proto/v1/tasks.proto
#	chasm/lib/scheduler/scheduler.go
#	chasm/lib/scheduler/scheduler_idle_tasks_test.go
#	chasm/lib/scheduler/scheduler_tasks.go
#	chasm/lib/scheduler/scheduler_test.go
#	chasm/lib/scheduler/spec_processor.go
#	chasm/lib/tests/gen/testspb/v1/service.pb.go
#	chasm/lib/tests/handler.go
#	chasm/lib/tests/library.go
#	chasm/lib/tests/payload.go
#	chasm/lib/tests/proto/v1/message.proto
#	chasm/lib/tests/proto/v1/request_response.proto
#	chasm/lib/tests/proto/v1/service.proto
#	chasm/lib/tests/tasks.go
#	chasm/lib/workflow/fx.go
#	chasm/lib/workflow/library.go
#	chasm/lib/workflow/workflow.go
#	chasm/library_core.go
#	chasm/ms_pointer.go
#	chasm/nexus_operation_processor.go
#	chasm/node_backend_mock.go
#	chasm/ref.go
#	chasm/ref_test.go
#	chasm/registrable_component.go
#	chasm/registrable_task.go
#	chasm/registry.go
#	chasm/registry_test.go
#	chasm/search_attribute.go
#	chasm/search_attribute_test.go
#	chasm/statemachine.go
#	chasm/task.go
#	chasm/task_mock.go
#	chasm/test_component_test.go
#	chasm/test_library_test.go
#	chasm/test_task_test.go
#	chasm/test_var_test.go
#	chasm/tree.go
#	chasm/tree_test.go
#	chasm/visibility.go
#	chasm/visibility_manager.go
#	chasm/visibility_manager_mock.go
#	chasm/visibility_test.go
#	chasm/visibility_value.go
#	chasm/visibility_value_test.go
#	chasm/workflow.go
#	client/admin/client_gen.go
#	client/admin/metric_client.go
#	client/admin/metric_client_gen.go
#	client/admin/retryable_client_gen.go
#	client/frontend/client_gen.go
#	client/frontend/metric_client.go
#	client/frontend/metric_client_gen.go
#	client/frontend/retryable_client_gen.go
#	client/history/client_gen.go
#	client/history/metric_client.go
#	client/history/metric_client_gen.go
#	client/history/retryable_client_gen.go
#	client/matching/README.md
#	client/matching/client.go
#	client/matching/client_gen.go
#	client/matching/loadbalancer.go
#	client/matching/metric_client.go
#	client/matching/metric_client_gen.go
#	cmd/tools/genrpcwrappers/main.go
#	cmd/tools/getproto/files.go
#	cmd/tools/getproto/main.go
#	common/api/metadata.go
#	common/archiver/README.md
#	common/archiver/gcloud/connector/client.go
#	common/archiver/provider/provider.go
#	common/archiver/provider/provider_mock.go
#	common/archiver/s3store/history_archiver.go
#	common/archiver/s3store/history_archiver_test.go
#	common/archiver/s3store/mocks/generate.go
#	common/archiver/s3store/mocks/s3api.go
#	common/archiver/s3store/util.go
#	common/archiver/s3store/visibility_archiver.go
#	common/archiver/s3store/visibility_archiver_test.go
#	common/authorization/authorizer.go
#	common/authorization/claim_mapper.go
#	common/authorization/default_authorizer.go
#	common/authorization/default_jwt_claim_mapper.go
#	common/authorization/default_token_key_provider.go
#	common/authorization/interceptor.go
#	common/authorization/interceptor_test.go
#	common/authorization/roles.go
#	common/cluster/metadata.go
#	common/cluster/metadata_test.go
#	common/config/config.go
#	common/config/config_template_embedded.yaml
#	common/config/persistence.go
#	common/config/persistence_test.go
#	common/constants.go
#	common/contextutil/metadata.go
#	common/contextutil/metadata_test.go
#	common/dynamicconfig/constants.go
#	common/dynamicconfig/shared_constants.go
#	common/enums/defaults.go
#	common/headers/caller_info.go
#	common/headers/headers.go
#	common/headers/version_checker.go
#	common/log/tag/values.go
#	common/log/zap_logger.go
#	common/membership/ringpop/factory.go
#	common/membership/ringpop/monitor.go
#	common/membership/ringpop/service_resolver.go
#	common/membership/ringpop/test_cluster.go
#	common/metrics/config.go
#	common/metrics/metric_defs.go
#	common/metrics/tags.go
#	common/metrics/tally_metrics_handler.go
#	common/metrics/tally_metrics_handler_test.go
#	common/metrics/task_queues.go
#	common/namespace/namespace.go
#	common/namespace/nsregistry/registry.go
#	common/namespace/nsregistry/registry_test.go
#	common/namespace/nsregistry/registry_watch_test.go
#	common/namespace/nsreplication/replication_task_executor.go
#	common/namespace/nsreplication/replication_task_executor_test.go
#	common/namespace/nsreplication/transmission_task_handler.go
#	common/namespace/nsreplication/transmission_task_handler_test.go
#	common/namespace/registry.go
#	common/namespace/registry_mock.go
#	common/namespace/replication_resolver.go
#	common/namespace/replication_resolver_test.go
#	common/nexus/callback_token.go
#	common/nexus/endpoint_registry.go
#	common/nexus/endpoint_registry_test.go
#	common/nexus/failure.go
#	common/nexus/failure_test.go
#	common/nexus/link_converter.go
#	common/nexus/link_converter_test.go
#	common/nexus/nexustest/server.go
#	common/nexus/payload_serializer.go
#	common/nexus/payload_serializer_test.go
#	common/payload/payload.go
#	common/payload/payload_test.go
#	common/payloads/payloads.go
#	common/persistence/cassandra/matching_task_store_queue.go
#	common/persistence/cassandra/matching_task_store_user_data.go
#	common/persistence/cassandra/matching_task_store_v1.go
#	common/persistence/cassandra/matching_task_store_v2.go
#	common/persistence/cassandra/queue_v2_store.go
#	common/persistence/data_interfaces.go
#	common/persistence/faultinjection/cluster_metadata_store_gen.go
#	common/persistence/faultinjection/data_store_factory.go
#	common/persistence/faultinjection/execution_store_gen.go
#	common/persistence/faultinjection/fault_generator.go
#	common/persistence/faultinjection/gowrap_template
#	common/persistence/faultinjection/metadata_store_gen.go
#	common/persistence/faultinjection/method_fault_generator.go
#	common/persistence/faultinjection/nexus_endpoint_store_gen.go
#	common/persistence/faultinjection/queue_gen.go
#	common/persistence/faultinjection/queue_v2_gen.go
#	common/persistence/faultinjection/shard_store_gen.go
#	common/persistence/faultinjection/store_fault_generator.go
#	common/persistence/faultinjection/task_store_gen.go
#	common/persistence/persistence_interface.go
#	common/persistence/persistencetest/queues.go
#	common/persistence/persistencetest/queues_test.go
#	common/persistence/serialization/codec.go
#	common/persistence/serialization/codec_test.go
#	common/persistence/serialization/serializer.go
#	common/persistence/serialization/task_serializers.go
#	common/persistence/serialization/task_serializers_test.go
#	common/persistence/sql/sqlplugin/mysql/session/session.go
#	common/persistence/sql/sqlplugin/mysql/visibility.go
#	common/persistence/sql/sqlplugin/postgresql/driver/interface.go
#	common/persistence/sql/sqlplugin/postgresql/driver/pgx.go
#	common/persistence/sql/sqlplugin/postgresql/driver/pq.go
#	common/persistence/sql/sqlplugin/postgresql/plugin.go
#	common/persistence/sql/sqlplugin/postgresql/session/session.go
#	common/persistence/sql/sqlplugin/sqlite/driver.go
#	common/persistence/sql/sqlplugin/sqlite/plugin.go
#	common/persistence/task_manager.go
#	common/persistence/tests/postgresql_test.go
#	common/persistence/tests/postgresql_test_util.go
#	common/persistence/tests/util.go
#	common/persistence/tests/visibility_persistence_suite.go
#	common/persistence/visibility/chasm_visibility_manager.go
#	common/persistence/visibility/chasm_visibility_manager_test.go
#	common/persistence/visibility/manager/visibility_manager.go
#	common/persistence/visibility/manager/visibility_manager_mock.go
#	common/persistence/visibility/store/elasticsearch/client/aws.go
#	common/persistence/visibility/store/elasticsearch/query_interceptors.go
#	common/persistence/visibility/store/elasticsearch/query_interceptors_test.go
#	common/persistence/visibility/store/elasticsearch/visibility_store.go
#	common/persistence/visibility/store/elasticsearch/visibility_store_read_test.go
#	common/persistence/visibility/store/query/converter.go
#	common/persistence/visibility/store/query/converter_test.go
#	common/persistence/visibility/store/sql/query_converter_legacy.go
#	common/persistence/visibility/store/sql/query_converter_legacy_test.go
#	common/persistence/visibility/store/sql/visibility_store.go
#	common/persistence/visibility/store/util.go
#	common/persistence/visibility/store/visibility_store.go
#	common/persistence/visibility/store/visibility_store_mock.go
#	common/persistence/visibility/visibility_manager_dual.go
#	common/persistence/visibility/visibility_manager_impl.go
#	common/persistence/visibility/visibility_manager_rate_limited.go
#	common/persistence/visibility/visiblity_manager_metrics.go
#	common/primitives/task_queues.go
#	common/quotas/clocked_rate_limiter.go
#	common/quotas/dynamic_rate_limiter_impl.go
#	common/quotas/priority_rate_limiter_impl.go
#	common/quotas/rate_burst.go
#	common/resource/fx.go
#	common/rpc/encryption/fixedTLSConfigProvider.go
#	common/rpc/encryption/local_store_tls_provider.go
#	common/rpc/encryption/tls_config_test.go
#	common/rpc/interceptor/dc_redirection_policy.go
#	common/rpc/interceptor/health_check.go
#	common/rpc/interceptor/logtags/admin_service_server_gen.go
#	common/rpc/interceptor/logtags/history_service_server_gen.go
#	common/rpc/interceptor/logtags/workflow_service_server_gen.go
#	common/rpc/interceptor/namespace_handover.go
#	common/rpc/interceptor/namespace_rate_limit.go
#	common/rpc/interceptor/namespace_validator.go
#	common/rpc/interceptor/namespace_validator_test.go
#	common/rpc/interceptor/rate_limit.go
#	common/rpc/interceptor/redirection.go
#	common/rpc/interceptor/redirection_test.go
#	common/rpc/interceptor/request_error_handler.go
#	common/rpc/interceptor/routing_key_interceptor_test.go
#	common/rpc/interceptor/service_error_interceptor.go
#	common/rpc/interceptor/service_error_interceptor_test.go
#	common/rpc/rpc.go
#	common/rpc/test/http_test.go
#	common/rpc/test/rpc_localstore_tls_test.go
#	common/searchattribute/encode.go
#	common/searchattribute/encode_test.go
#	common/searchattribute/manager.go
#	common/searchattribute/mapper.go
#	common/searchattribute/mapper_test.go
#	common/searchattribute/name_type_map.go
#	common/searchattribute/name_type_map_test.go
#	common/searchattribute/sadefs/encode_value.go
#	common/searchattribute/sadefs/encode_value_test.go
#	common/searchattribute/sadefs/util.go
#	common/searchattribute/search_attirbute.go
#	common/searchattribute/stringify.go
#	common/searchattribute/stringify_test.go
#	common/searchattribute/system_provider.go
#	common/searchattribute/test_provider.go
#	common/searchattribute/validator.go
#	common/serviceerror/convert.go
#	common/tasks/interleaved_weighted_round_robin_test.go
#	common/testing/historyrequire/history_require.go
#	common/testing/mockapi/workflowservicemock/v1/service_grpc.pb.mock.go
#	common/testing/mocksdk/client_mock.go
#	common/testing/protorequire/require.go
#	common/testing/testhooks/hooks.go
#	common/testing/testhooks/test_impl.go
#	common/testing/testlogger/testlogger.go
#	common/testing/testvars/test_vars.go
#	common/tqid/task_queue_id.go
#	common/tqid/task_queue_id_test.go
#	common/tqid/task_queue_validator.go
#	common/util/util.go
#	common/util/wildcard.go
#	common/worker_versioning/version_membership_cache.go
#	common/worker_versioning/worker_versioning.go
#	common/worker_versioning/worker_versioning_test.go
#	components/callbacks/config.go
#	components/callbacks/config_test.go
#	components/callbacks/request.go
#	components/callbacks/request_test.go
#	components/nexusoperations/config.go
#	components/nexusoperations/executors_test.go
#	components/nexusoperations/fx.go
#	components/nexusoperations/workflow/commands.go
#	components/nexusoperations/workflow/commands_test.go
#	config/development-cluster-a.yaml
#	config/development-cluster-b.yaml
#	config/development-cluster-c.yaml
#	config/dynamicconfig/development-cass.yaml
#	config/dynamicconfig/development-sql.yaml
#	config/dynamicconfig/development-xdc.yaml
#	develop/docker-compose/docker-compose.yml
#	develop/docker-compose/grafana/provisioning/tempo/tempo.yaml
#	develop/github/docker-compose.yml
#	docker/docker-bake.hcl
#	docker/targets/admin-tools.Dockerfile
#	docker/targets/server.Dockerfile
#	docs/Makefile
#	docs/_assets/matching-context.d2
#	docs/_assets/retries.d2
#	docs/architecture/chasm.md
#	docs/architecture/nexus.md
#	docs/development/macos/cassandra.md
#	docs/development/testing.md
#	proto/internal/buf.yaml
#	proto/internal/temporal/server/api/adminservice/v1/request_response.proto
#	proto/internal/temporal/server/api/adminservice/v1/service.proto
#	proto/internal/temporal/server/api/archiver/v1/message.proto
#	proto/internal/temporal/server/api/batch/v1/request_response.proto
#	proto/internal/temporal/server/api/checksum/v1/message.proto
#	proto/internal/temporal/server/api/cli/v1/message.proto
#	proto/internal/temporal/server/api/clock/v1/message.proto
#	proto/internal/temporal/server/api/cluster/v1/message.proto
#	proto/internal/temporal/server/api/common/v1/api_category.proto
#	proto/internal/temporal/server/api/common/v1/dlq.proto
#	proto/internal/temporal/server/api/deployment/v1/message.proto
#	proto/internal/temporal/server/api/enums/v1/cluster.proto
#	proto/internal/temporal/server/api/enums/v1/common.proto
#	proto/internal/temporal/server/api/enums/v1/fairness_state.proto
#	proto/internal/temporal/server/api/enums/v1/nexus.proto
#	proto/internal/temporal/server/api/enums/v1/predicate.proto
#	proto/internal/temporal/server/api/enums/v1/replication.proto
#	proto/internal/temporal/server/api/enums/v1/task.proto
#	proto/internal/temporal/server/api/enums/v1/workflow.proto
#	proto/internal/temporal/server/api/enums/v1/workflow_task_type.proto
#	proto/internal/temporal/server/api/errordetails/v1/message.proto
#	proto/internal/temporal/server/api/health/v1/message.proto
#	proto/internal/temporal/server/api/history/v1/message.proto
#	proto/internal/temporal/server/api/historyservice/v1/request_response.proto
#	proto/internal/temporal/server/api/historyservice/v1/service.proto
#	proto/internal/temporal/server/api/matchingservice/v1/request_response.proto
#	proto/internal/temporal/server/api/matchingservice/v1/service.proto
#	proto/internal/temporal/server/api/metrics/v1/message.proto
#	proto/internal/temporal/server/api/namespace/v1/message.proto
#	proto/internal/temporal/server/api/persistence/v1/chasm.proto
#	proto/internal/temporal/server/api/persistence/v1/chasm_visibility.proto
#	proto/internal/temporal/server/api/persistence/v1/cluster_metadata.proto
#	proto/internal/temporal/server/api/persistence/v1/executions.proto
#	proto/internal/temporal/server/api/persistence/v1/history_tree.proto
#	proto/internal/temporal/server/api/persistence/v1/hsm.proto
#	proto/internal/temporal/server/api/persistence/v1/namespaces.proto
#	proto/internal/temporal/server/api/persistence/v1/nexus.proto
#	proto/internal/temporal/server/api/persistence/v1/predicates.proto
#	proto/internal/temporal/server/api/persistence/v1/queue_metadata.proto
#	proto/internal/temporal/server/api/persistence/v1/queues.proto
#	proto/internal/temporal/server/api/persistence/v1/task_queues.proto
#	proto/internal/temporal/server/api/persistence/v1/tasks.proto
#	proto/internal/temporal/server/api/persistence/v1/update.proto
#	proto/internal/temporal/server/api/persistence/v1/workflow_mutable_state.proto
#	proto/internal/temporal/server/api/replication/v1/message.proto
#	proto/internal/temporal/server/api/routing/v1/extension.proto
#	proto/internal/temporal/server/api/schedule/v1/message.proto
#	proto/internal/temporal/server/api/taskqueue/v1/message.proto
#	proto/internal/temporal/server/api/testservice/v1/request_response.proto
#	proto/internal/temporal/server/api/testservice/v1/service.proto
#	proto/internal/temporal/server/api/token/v1/message.proto
#	proto/internal/temporal/server/api/workflow/v1/message.proto
#	service/frontend/admin_handler.go
#	service/frontend/admin_handler_test.go
#	service/frontend/configs/quotas.go
#	service/frontend/configs/quotas_test.go
#	service/frontend/errors.go
#	service/frontend/fx.go
#	service/frontend/fx_test.go
#	service/frontend/health_check_test.go
#	service/frontend/namespace_handler.go
#	service/frontend/namespace_handler_test.go
#	service/frontend/nexus_completion_http_handler.go
#	service/frontend/nexus_handler.go
#	service/frontend/nexus_handler_test.go
#	service/frontend/nexus_operation_http_handler.go
#	service/frontend/nexus_operation_http_handler_test.go
#	service/frontend/operator_handler.go
#	service/frontend/operator_handler_test.go
#	service/frontend/service.go
#	service/frontend/workflow_handler.go
#	service/frontend/workflow_handler_second_test.go
#	service/frontend/workflow_handler_test.go
#	service/fx.go
#	service/history/api/command_attr_validator.go
#	service/history/api/command_attr_validator_test.go
#	service/history/api/create_workflow_util.go
#	service/history/api/describeworkflow/api.go
#	service/history/api/get_workflow_util.go
#	service/history/api/multioperation/api.go
#	service/history/api/namespace.go
#	service/history/api/pauseactivity/api.go
#	service/history/api/pollupdate/api_test.go
#	service/history/api/queryworkflow/api.go
#	service/history/api/recordactivitytaskstarted/api.go
#	service/history/api/recordactivitytaskstarted/api_test.go
#	service/history/api/recordworkflowtaskstarted/api.go
#	service/history/api/removesignalmutablestate/api.go
#	service/history/api/resetactivity/api.go
#	service/history/api/resetworkflow/api.go
#	service/history/api/respondactivitytaskcanceled/api.go
#	service/history/api/respondactivitytaskcompleted/api.go
#	service/history/api/respondactivitytaskfailed/api.go
#	service/history/api/respondactivitytaskfailed/api_test.go
#	service/history/api/respondworkflowtaskcompleted/api.go
#	service/history/api/respondworkflowtaskcompleted/api_test.go
#	service/history/api/respondworkflowtaskcompleted/workflow_task_completed_handler.go
#	service/history/api/respondworkflowtaskcompleted/workflow_task_completed_handler_test.go
#	service/history/api/respondworkflowtaskfailed/api.go
#	service/history/api/signalwithstartworkflow/api.go
#	service/history/api/signalwithstartworkflow/convert.go
#	service/history/api/signalwithstartworkflow/signal_with_start_workflow.go
#	service/history/api/signalwithstartworkflow/signal_with_start_workflow_test.go
#	service/history/api/signalworkflow/api.go
#	service/history/api/startworkflow/api.go
#	service/history/api/unpauseactivity/api.go
#	service/history/api/updateactivityoptions/api.go
#	service/history/api/updateactivityoptions/api_test.go
#	service/history/api/updateworkflow/api.go
#	service/history/api/updateworkflowoptions/api.go
#	service/history/api/updateworkflowoptions/api_test.go
#	service/history/api/verifychildworkflowcompletionrecorded/api.go
#	service/history/api/verifyfirstworkflowtaskscheduled/api_test.go
#	service/history/api/worker_versioning_util.go
#	service/history/api/workflow_id_dedup.go
#	service/history/api/workflow_id_dedup_test.go
#	service/history/archival_queue_factory_test.go
#	service/history/chasm_engine.go
#	service/history/chasm_engine_test.go
#	service/history/chasm_task_util.go
#	service/history/configs/config.go
#	service/history/configs/quotas.go
#	service/history/consts/const.go
#	service/history/deletemanager/delete_manager.go
#	service/history/deletemanager/delete_manager_test.go
#	service/history/fx.go
#	service/history/handler.go
#	service/history/history_engine.go
#	service/history/history_engine2_test.go
#	service/history/history_engine_factory.go
#	service/history/history_engine_test.go
#	service/history/history_test.go
#	service/history/historybuilder/event_factory.go
#	service/history/historybuilder/event_store.go
#	service/history/historybuilder/history_builder.go
#	service/history/historybuilder/history_builder_categorization_test.go
#	service/history/historybuilder/history_builder_test.go
#	service/history/interfaces/chasm_tree.go
#	service/history/interfaces/chasm_tree_mock.go
#	service/history/interfaces/mutable_state.go
#	service/history/interfaces/mutable_state_mock.go
#	service/history/interfaces/shard_context.go
#	service/history/interfaces/shard_context_mock.go
#	service/history/interfaces/workflow_context.go
#	service/history/interfaces/workflow_context_mock.go
#	service/history/ndc/events_reapplier_test.go
#	service/history/ndc/transaction_manager.go
#	service/history/ndc/transaction_manager_existing_workflow.go
#	service/history/ndc/transaction_manager_existing_workflow_test.go
#	service/history/ndc/transaction_manager_new_workflow.go
#	service/history/ndc/transaction_manager_new_workflow_test.go
#	service/history/ndc/workflow.go
#	service/history/ndc/workflow_mock.go
#	service/history/ndc/workflow_resetter.go
#	service/history/ndc/workflow_resetter_test.go
#	service/history/ndc/workflow_state_replicator_test.go
#	service/history/ndc_standby_task_util.go
#	service/history/ndc_task_util.go
#	service/history/outbound_queue_active_task_executor.go
#	service/history/outbound_queue_active_task_executor_test.go
#	service/history/outbound_queue_factory.go
#	service/history/outbound_queue_standby_task_executor.go
#	service/history/outbound_queue_standby_task_executor_test.go
#	service/history/queue_factory_base.go
#	service/history/queue_factory_base_test.go
#	service/history/queues/active_standby_executor.go
#	service/history/queues/active_standby_executor_test.go
#	service/history/queues/dlq_writer.go
#	service/history/queues/dlq_writer_test.go
#	service/history/queues/executable.go
#	service/history/queues/executable_factory.go
#	service/history/queues/executable_mock.go
#	service/history/queues/executable_test.go
#	service/history/queues/grouper.go
#	service/history/queues/metrics.go
#	service/history/queues/metrics_test.go
#	service/history/queues/priority_assigner.go
#	service/history/queues/queue_base.go
#	service/history/queues/queue_immediate.go
#	service/history/queues/queue_immediate_test.go
#	service/history/queues/reader.go
#	service/history/queues/scheduler.go
#	service/history/queues/speculative_workflow_task_timeout_queue.go
#	service/history/replication/ack_manager.go
#	service/history/replication/dlq_writer.go
#	service/history/replication/dlq_writer_test.go
#	service/history/replication/executable_sync_versioned_transition_task.go
#	service/history/replication/executable_task.go
#	service/history/replication/executable_task_converter.go
#	service/history/replication/executable_task_mock.go
#	service/history/replication/executable_task_tool_box.go
#	service/history/replication/executable_verify_versioned_transition_task.go
#	service/history/replication/fx.go
#	service/history/replication/metrics.go
#	service/history/replication/progress_cache.go
#	service/history/replication/progress_cache_test.go
#	service/history/replication/raw_task_converter.go
#	service/history/replication/raw_task_converter_test.go
#	service/history/replication/stream_receiver.go
#	service/history/replication/stream_receiver_monitor.go
#	service/history/replication/stream_receiver_monitor_test.go
#	service/history/replication/stream_sender.go
#	service/history/replication/task_processor.go
#	service/history/replication/task_processor_manager.go
#	service/history/replication/task_processor_manager_test.go
#	service/history/replication/task_processor_test.go
#	service/history/service.go
#	service/history/shard/context_factory.go
#	service/history/shard/context_impl.go
#	service/history/shard/context_test.go
#	service/history/shard/context_testutil.go
#	service/history/shard/controller_test.go
#	service/history/shard/fx.go
#	service/history/tasks/chasm_task.go
#	service/history/tasks/delete_workflow_execution_stage.go
#	service/history/tasks/predicates.go
#	service/history/tasks/state_machine_task.go
#	service/history/tasks/task.go
#	service/history/tasks/task_mock.go
#	service/history/tasks/utils.go
#	service/history/timer_queue_active_task_executor.go
#	service/history/timer_queue_active_task_executor_test.go
#	service/history/timer_queue_standby_task_executor.go
#	service/history/timer_queue_standby_task_executor_test.go
#	service/history/timer_queue_task_executor_base.go
#	service/history/timer_queue_task_executor_base_test.go
#	service/history/transfer_queue_active_task_executor.go
#	service/history/transfer_queue_active_task_executor_test.go
#	service/history/transfer_queue_factory.go
#	service/history/transfer_queue_standby_task_executor.go
#	service/history/transfer_queue_standby_task_executor_test.go
#	service/history/visibility_queue_factory.go
#	service/history/visibility_queue_task_executor.go
#	service/history/visibility_queue_task_executor_test.go
#	service/history/worker_versioning_util.go
#	service/history/workflow/activity.go
#	service/history/workflow/cache/cache.go
#	service/history/workflow/command_handler.go
#	service/history/workflow/context.go
#	service/history/workflow/fx.go
#	service/history/workflow/metrics.go
#	service/history/workflow/metrics_test.go
#	service/history/workflow/mutable_state_impl.go
#	service/history/workflow/mutable_state_impl_restart_activity_test.go
#	service/history/workflow/mutable_state_impl_test.go
#	service/history/workflow/mutable_state_rebuilder.go
#	service/history/workflow/mutable_state_rebuilder_test.go
#	service/history/workflow/noop_chasm_tree.go
#	service/history/workflow/retry.go
#	service/history/workflow/task_generator.go
#	service/history/workflow/task_generator_mock.go
#	service/history/workflow/task_generator_provider.go
#	service/history/workflow/task_generator_test.go
#	service/history/workflow/task_refresher.go
#	service/history/workflow/timer_sequence.go
#	service/history/workflow/update/abort_reason.go
#	service/history/workflow/update/errors_failures.go
#	service/history/workflow/update/export_test.go
#	service/history/workflow/update/store.go
#	service/history/workflow/update/store_mock_test.go
#	service/history/workflow/update/update.go
#	service/history/workflow/update/update_test.go
#	service/history/workflow/update/validation.go
#	service/history/workflow/util.go
#	service/history/workflow/workflow_task_state_machine.go
#	service/history/workflow/workflow_test/mutable_state_impl_test.go
#	service/matching/backlog_manager_test.go
#	service/matching/config.go
#	service/matching/configs/quotas.go
#	service/matching/counter/cmsketch.go
#	service/matching/counter/cmsketch_test.go
#	service/matching/counter/hybrid.go
#	service/matching/db.go
#	service/matching/fair_backlog_manager.go
#	service/matching/fair_task_reader.go
#	service/matching/forwarder.go
#	service/matching/fx.go
#	service/matching/handler.go
#	service/matching/handler_test.go
#	service/matching/matcher.go
#	service/matching/matcher_data.go
#	service/matching/matcher_data_test.go
#	service/matching/matching_engine.go
#	service/matching/matching_engine_test.go
#	service/matching/physical_task_queue_key.go
#	service/matching/physical_task_queue_key_test.go
#	service/matching/physical_task_queue_manager.go
#	service/matching/physical_task_queue_manager_interface.go
#	service/matching/physical_task_queue_manager_mock.go
#	service/matching/physical_task_queue_manager_test.go
#	service/matching/pri_backlog_manager.go
#	service/matching/pri_forwarder.go
#	service/matching/pri_matcher.go
#	service/matching/pri_matcher_test.go
#	service/matching/pri_task_reader.go
#	service/matching/task.go
#	service/matching/task_queue_partition_manager.go
#	service/matching/task_queue_partition_manager_test.go
#	service/matching/task_tracker.go
#	service/matching/task_tracker_test.go
#	service/matching/task_validation.go
#	service/matching/user_data_manager.go
#	service/matching/user_data_manager_test.go
#	service/matching/workers/registry.go
#	service/matching/workers/registry_impl.go
#	service/matching/workers/registry_impl_test.go
#	service/matching/workers/registry_test.go
#	service/matching/workers/worker_query_engine.go
#	service/matching/workers/worker_query_engine_test.go
#	service/worker/batcher/activities.go
#	service/worker/batcher/activities_test.go
#	service/worker/deletenamespace/deleteexecutions/activities.go
#	service/worker/deletenamespace/deleteexecutions/workflow_test.go
#	service/worker/deletenamespace/fx.go
#	service/worker/dummy/workflow.go
#	service/worker/fx.go
#	service/worker/migration/activities.go
#	service/worker/migration/activities_test.go
#	service/worker/migration/force_replication_workflow.go
#	service/worker/migration/force_replication_workflow_test.go
#	service/worker/migration/fx.go
#	service/worker/migration/handover_workflow.go
#	service/worker/migration/handover_workflow_test.go
#	service/worker/scheduler/activities.go
#	service/worker/scheduler/activities_test.go
#	service/worker/scheduler/workflow.go
#	service/worker/workerdeployment/activities.go
#	service/worker/workerdeployment/client.go
#	service/worker/workerdeployment/fx.go
#	service/worker/workerdeployment/util.go
#	service/worker/workerdeployment/util_test.go
#	service/worker/workerdeployment/version_activities.go
#	service/worker/workerdeployment/version_workflow.go
#	service/worker/workerdeployment/version_workflow_test.go
#	service/worker/workerdeployment/workflow.go
#	service/worker/workerdeployment/workflow_test.go
#	temporal/fx.go
#	temporal/server_option.go
#	temporal/server_options.go
#	tests/acquire_shard_test.go
#	tests/activity_api_batch_reset_test.go
#	tests/activity_api_batch_unpause_test.go
#	tests/activity_api_batch_update_options_test.go
#	tests/activity_api_pause_test.go
#	tests/activity_api_reset_test.go
#	tests/activity_api_rules_test.go
#	tests/activity_api_update_test.go
#	tests/activity_test.go
#	tests/add_tasks_test.go
#	tests/admin_test.go
#	tests/advanced_visibility_test.go
#	tests/archival_test.go
#	tests/callbacks_migration_test.go
#	tests/callbacks_test.go
#	tests/cancel_workflow_test.go
#	tests/chasm_test.go
#	tests/child_workflow_test.go
#	tests/client_data_converter_test.go
#	tests/client_misc_test.go
#	tests/continue_as_new_test.go
#	tests/describe_test.go
#	tests/dlq_test.go
#	tests/links_test.go
#	tests/max_buffered_event_test.go
#	tests/namespace_interceptor_test.go
#	tests/namespace_test.go
#	tests/nexus_api_test.go
#	tests/nexus_api_validation_test.go
#	tests/nexus_endpoint_test.go
#	tests/nexus_test_base.go
#	tests/nexus_workflow_test.go
#	tests/pause_workflow_execution_test.go
#	tests/premature_eos_test.go
#	tests/priority_fairness_test.go
#	tests/purge_dlq_tasks_api_test.go
#	tests/query_workflow_test.go
#	tests/relay_task_test.go
#	tests/schedule_migration_test.go
#	tests/schedule_test.go
#	tests/signal_workflow_test.go
#	tests/sizelimit_test.go
#	tests/stickytq_test.go
#	tests/task_queue_stats_test.go
#	tests/task_queue_test.go
#	tests/testcore/context.go
#	tests/testcore/dynamic_config_overrides.go
#	tests/testcore/functional_test_base.go
#	tests/testcore/matching_behavior.go
#	tests/testcore/onebox.go
#	tests/testcore/shard_salt.txt
#	tests/testcore/test_cluster.go
#	tests/testcore/test_cluster_pool.go
#	tests/testcore/test_env.go
#	tests/transient_task_test.go
#	tests/update_workflow_sdk_test.go
#	tests/update_workflow_test.go
#	tests/user_metadata_test.go
#	tests/user_timers_test.go
#	tests/versioning_3_test.go
#	tests/versioning_test.go
#	tests/worker_deployment_test.go
#	tests/worker_deployment_version_test.go
#	tests/workflow_alias_search_attribute_test.go
#	tests/workflow_buffered_events_test.go
#	tests/workflow_delete_execution_test.go
#	tests/workflow_failures_test.go
#	tests/workflow_memo_test.go
#	tests/workflow_task_reported_problems_test.go
#	tests/workflow_test.go
#	tests/workflow_timer_test.go
#	tests/workflow_visibility_test.go
#	tests/xdc/base.go
#	tests/xdc/chasm_test.go
#	tests/xdc/failover_test.go
#	tests/xdc/history_replication_dlq_test.go
#	tests/xdc/history_replication_signals_and_updates_test.go
#	tests/xdc/nexus_request_forwarding_test.go
#	tests/xdc/nexus_state_replication_test.go
#	tests/xdc/stream_based_replication_test.go
#	tests/xdc/visibility_test.go
#	tools/elasticsearch/handler.go
#	tools/elasticsearch/main.go
#	tools/elasticsearch/tasks.go
#	tools/flakereport/flakereport.go
#	tools/flakereport/github.go
#	tools/flakereport/slack.go
#	tools/flakereport/types.go
#	tools/flakereport/writer.go
#	tools/tdbg/chasm_registry.go
#	tools/tdbg/commands.go
#	tools/tdbg/flags.go
#	tools/tdbg/task_queue_commands.go
#	tools/tdbg/task_queue_commands_test.go
#	tools/tdbg/tdbg_commands.go
#	tools/tdbg/util.go
#	tools/testrunner/junit.go
#	tools/testrunner/junit_test.go
#	tools/testrunner/log.go
#	tools/testrunner/log_test.go
#	tools/testrunner/testdata/junit-alerts-output.xml
#	tools/testrunner/testdata/junit-crash-output.xml
#	tools/testrunner/testdata/junit-empty.xml
#	tools/testrunner/testdata/junit-timeout-output.xml
#	tools/testrunner/testrunner.go
#	tools/testrunner/testrunner_test.go
2026-06-02 10:02:39 -07:00
zeekayandGitHub f5a902c0c1 Merge pull request #3 from hanzoai/contract/canonical-async-substrate
docs: add canonical Hanzo Tasks contract
2026-06-01 21:34:01 -07:00
zeekay 04e7d56810 docs: add canonical Hanzo Tasks contract
CONTRACT.md is the single durable async substrate spec for every Hanzo +
Liquidity Go service. Covers: when to use tasks vs sync, task definition
shape, worker registration, client API, ZAP transport, per-tenant
namespace isolation, failure modes, observability.

Replaces ad-hoc per-service taskqueue wrappers and the lingering
go.temporal.io/sdk imports in Liquidity ats/bd/ta.
2026-06-01 17:47:36 -07:00
zeekay 787066932e Merge remote-tracking branch 'origin/main' 2026-06-01 16:11:21 -07:00
zeekay a504abc23d merge: feat/scale-standard 2026-06-01 16:11:20 -07:00
zeekay 1e76fabaff chore: gitignore build artifacts + drop 80 tracked files
dist/.next/target/etc. should never have been tracked.
Regenerated by build pipeline.
2026-06-01 15:19:36 -07:00
zeekayandGitHub 51fa479364 build(tasks): GOEXPERIMENT=jsonv2 per SCALE_STANDARD (#1)
* docs(llm): explicit Upstream attribution line

LICENSE-attested or repo-attested upstream is now called out at the
top of LLM.md alongside the project description, so downstream
audits (universe/docs/PRODUCTS.md) can rely on a single canonical
location for the OSS lineage statement.

* build(tasks): GOEXPERIMENT=jsonv2 in Dockerfile per SCALE_STANDARD

Per SCALE_STANDARD.md §2 — every Go production Dockerfile that emits
JSON to a client builds with GOEXPERIMENT=jsonv2. Verified on
hanzoai/zip's json_bench_test.go:
- Edge POST roundtrip: -12% time, -23% allocs
- Marshal-only: -22% time
- Unmarshal-only: -19% time, -25% allocs

The conn-memory regression test is deferred to a follow-up that
migrates tasksd's net/http listener to zip per §9 step-1; net/http
has a fixed 3-goroutine-per-request overhead that violates §3's 1:1
goroutine-to-conn invariant.
2026-05-29 21:05:26 -07:00
zeekay fd23c50704 build(tasks): GOEXPERIMENT=jsonv2 in Dockerfile per SCALE_STANDARD
Per SCALE_STANDARD.md §2 — every Go production Dockerfile that emits
JSON to a client builds with GOEXPERIMENT=jsonv2. Verified on
hanzoai/zip's json_bench_test.go:
- Edge POST roundtrip: -12% time, -23% allocs
- Marshal-only: -22% time
- Unmarshal-only: -19% time, -25% allocs

The conn-memory regression test is deferred to a follow-up that
migrates tasksd's net/http listener to zip per §9 step-1; net/http
has a fixed 3-goroutine-per-request overhead that violates §3's 1:1
goroutine-to-conn invariant.
2026-05-19 12:32:36 -07:00
zeekay 85901646ae docs(llm): explicit Upstream attribution line
LICENSE-attested or repo-attested upstream is now called out at the
top of LLM.md alongside the project description, so downstream
audits (universe/docs/PRODUCTS.md) can rely on a single canonical
location for the OSS lineage statement.
2026-05-18 21:35:48 -07:00
zeekay e61c98608b deps: luxfi/crypto v1.19.0 2026-05-13 12:02:38 -07:00
zeekay 8fb2c40f01 go.mod: bump go directive to 1.26.3 (security advisory) 2026-05-12 21:26:57 -07:00
zeekay 9b9ce37532 docs: enforce v1.x.x policy; v2/v3 tags deleted, continue from v1.43 2026-04-30 00:31:18 -07:00
zeekay 6465803dbe chore: ignore tasks-data test artifacts in pkg/tasks 2026-04-30 00:09:50 -07:00
zeekay 45bd80a26d feat(tasks): v3.9.0 — distributed engine: per-NS SQLite shards + PQ consensus + sticky routing
Architecture
  One SQLite shard per (org, namespace) under <DataDir>/<org>/<ns>.db
  with WAL mode, single writer, 5s busy timeout. Replaces the prior
  shared memdb/zapdb store. Shard manager opens/caches/idle-evicts;
  prefix scans, namespace isolation, and cross-restart durability all
  proven by tests.

Replication (post-quantum, native)
  New pkg/tasks/replication/ exposes a Replicator interface with two
  drivers:
    local  — single-node passthrough (default for embedded/dev)
    quasar — wraps github.com/luxfi/consensus NewPQ (BLS + Corona
             dual-threshold). On every WAL-affecting op the shard
             builds a Frame, calls Propose, awaits Decision, applies
             on Accept. Followers receive accepted frames via the
             same Subscribe path so every node converges.

Sticky task-queue routing
  New pkg/tasks/routing/ — rendezvous-style smallest-hash leader
  election keyed by SHA-256(shard|taskQueue|seed). OnChange fan-out
  re-hashes on cluster membership change. Dispatcher consults Router
  before accepting subscriptions and forwards non-leader requests.

Namespace migration
  New pkg/tasks/migration/ — lock → checkpoint → copy → unlock with
  a job lifecycle (pending|locking|copying|replaying|released|failed).
  CLI: `tasksd migrate --org <id> --namespace <name> --to <node>`.
  HTTP: POST /v1/tasks/namespaces/{ns}/migrate.

New env / flags
  --data / TASKSD_DATA_DIR        shard root (./tasks-data)
  --replicator / TASKSD_REPLICATOR local | quasar (default local)
  --node-id / TASKSD_NODE_ID      stable id (required for quasar)
  --validators / TASKSD_VALIDATORS CSV host:port
  --validator-key / TASKSD_VALIDATOR_KEY (reserved for PQ key path)
  TASKSD_STORE                    sqlite | memory (default sqlite)

New routes
  GET  /v1/tasks/cluster
  GET  /v1/tasks/cluster/health
  POST /v1/tasks/namespaces/{ns}/migrate

UI bundle (synced)
  Cluster page with status / validators / shards / leader-map.
  NamespaceDetail "Migrate to node" button gated by
  canWriteNamespace + cluster.enabled. MigrationDialog enforces
  typed-name confirmation. Sidebar Cluster nav hidden when running
  single-node.

Tests
  +33 backend tests (store: 11, replication: 10, routing: 5,
  migration: 3, cluster routes: 2, store factory: 2). All packages
  PASS with -race; go vet clean.
  +13 UI tests (effectiveHealth: 6, canSubmitMigration: 4,
  useCluster: 3). 169 total UI tests, 1 pre-existing skip.

Migration v3.8.x → v3.9.0
  Fresh-data startup. zapdb backend dropped. Operators drain old
  cluster, snapshot for archival, deploy v3.9.0 with new --data
  directory. To enable HA, scale to 3+ replicas with --replicator
  quasar and matching --node-id / --validators.
2026-04-30 00:09:39 -07:00
zeekay a3cbc7c7f5 fix(tasks): sync admin-tasks bundle for Deployment type alignment
Bundles the wire-shape fix (Deployment: name + versions). Front-end was
reading seriesName/buildIds from the v3.7.x type which v3.8.0 renamed.
1 Deployment list page rendered blank with TypeError; now renders
correctly.
2026-04-29 20:38:37 -07:00
zeekay 18c2c5cf0b feat(tasks): v3.8.0 — full parity wave (activities, deployment CRUD, validate)
Backend additions
  Standalone activities — first-class records keyed by (ns, activityId,
  runId). Engine: StartActivity, ListActivities, DescribeActivity,
  CancelActivity, CompleteActivity, FailActivity, HeartbeatActivity
  (FSM-rejecting + auto SCHEDULED→STARTED), GetActivityHistory.
  Heartbeat tolerated only on running. Idempotent on requestId.

  Deployments — full CRUD. CreateDeployment(ns,name,desc,owner,compute)
  rejects dup. UpdateDeployment patches description/owner/compute.
  DeleteDeployment refuses if versions exist unless force. CreateVersion
  promotes first version to current; rejects dup buildId. UpdateVersion
  metadata-only. ValidateVersion returns synthetic snapshot pending
  worker SDK runtime.

New HTTP routes (15)
  GET    /v1/tasks/namespaces/{ns}/activities
  POST   /v1/tasks/namespaces/{ns}/activities
  GET    /v1/tasks/namespaces/{ns}/activities/{id}/{run}
  POST   .../{id}/{run}/{cancel,complete,fail,heartbeat}
  GET    .../{id}/{run}/history
  POST   /v1/tasks/namespaces/{ns}/deployments  (create, 409 on dup)
  GET    /v1/tasks/namespaces/{ns}/deployments/{name}
  POST   /v1/tasks/namespaces/{ns}/deployments/{name}  (patch)
  DELETE /v1/tasks/namespaces/{ns}/deployments/{name}?force=
  POST   /v1/tasks/namespaces/{ns}/deployments/{name}/versions
  POST   .../versions/{buildId}  (patch metadata)
  POST   .../versions/{buildId}/validate

Tests
  +24 top-level test functions across activities and deployments.
  go test ./... -race -count=1 PASS, go vet clean.

UI bundle (synced)
  Activities feature — list/start/detail with 5 tabs (summary, history,
  workers, search-attrs, user-metadata). Action menu FSM-gated; capability-
  gated. Activity history reuses HistoryTree.

  Worker-deployment CRUD — Create/Edit/Delete deployments, version
  Create/Edit/Delete, validate-connection modal.

  Workflows-list polish — bulk-select toolbar (Cancel/Terminate/Reset/
  Signal across selected, builds Batches.create with WorkflowId IN(...)),
  saved-view persistence in localStorage keyed by (org, namespace),
  filter chips (status, time range, search-attribute) round-tripped
  through parseSearchQuery.

  Polish — ConfigurableTableHeadersDrawer + useTableColumns hook;
  TimelinePane (Gantt over activities/timers/child-workflows);
  PendingNexusPane; PayloadInputWithEncoding + PayloadDecoder +
  RetryPolicyInput reusable widgets.

UI tests: 156 passed, 1 skipped, 0 failed (was 115; +41 new).
2026-04-29 20:31:55 -07:00
zeekay 056a57ba71 fix(tasksd): /v1/tasks/settings unauthenticated for SPA bootstrap 2026-04-29 18:14:32 -07:00