Problem
Running the threads service on Mac via bootstrap fails:
Failed to pull image "ghcr.io/agynio/threads:v0.1.2": rpc error: code = NotFound desc = failed to pull and unpack image "ghcr.io/agynio/threads:v0.1.2": no match for platform in manifest: not found
The v0.1.2 image tag was built by an old release workflow that only produces linux/amd64. Mac (Apple Silicon / arm64) has no matching manifest.
Root Cause
The repo has two fully diverged branches:
main: Has v0.2.0 features (allow app senders, identity/authorization) but uses an old CI/CD workflow that builds amd64-only images and tags them with v prefix (e.g., v0.1.2).
noa/issue-1 (current default branch): Has aligned CI/CD (multi-arch builds per architecture spec), aligned Dockerfile, service-base Helm dependency, DevSpace config, but is missing v0.2.0 features.
When v0.1.2 was tagged, both workflows ran — the old one pushed v0.1.2 (amd64-only) and the new one pushed 0.1.2 (multi-arch but without v prefix). Bootstrap references v0.1.2 → gets the amd64-only image.
Additionally, the Helm chart on noa/issue-1 has a lint bug — all service-base includes are in a single service-base.yaml file, which produces invalid YAML when rendered (missing document separators between resources).
Required Changes
1. Reconcile branches in agynio/threads
Use noa/issue-1 as the base (aligned CI/CD, Dockerfile, Helm structure). Apply v0.2.0 feature code from main on top. Work on the main branch so it becomes the single source of truth.
Files to keep from noa/issue-1 as-is:
.github/workflows/release.yml — multi-arch CI/CD
README.md
go.mod, go.sum
migrations/0001_init.sql, migrations/embed.go
internal/db/migrate.go, internal/store/types.go
Files to delete (from main, not carried forward):
Makefile
buf.lock
charts/threads/templates/_helpers.tpl
charts/threads/templates/deployment.yaml (custom standalone)
charts/threads/templates/service.yaml (custom standalone)
charts/threads/templates/serviceaccount.yaml (custom standalone)
Files to delete from noa/issue-1:
charts/threads/templates/service-base.yaml (broken single-file pattern)
2. Fix Helm chart lint issue
Replace the single service-base.yaml with individual template files (one per resource), matching the pattern used by agynio/gateway and agynio/chat:
| File |
Content |
templates/deployment.yaml |
{{- include "service-base.deployment" . -}} |
templates/service.yaml |
{{- include "service-base.service" . -}} |
templates/serviceaccount.yaml |
{{- include "service-base.serviceAccount" . -}} |
templates/rbac.yaml |
{{- include "service-base.rbac" . -}} |
templates/hpa.yaml |
{{- include "service-base.hpa" . -}} |
templates/ingress.yaml |
{{- include "service-base.ingress" . -}} |
templates/pdb.yaml |
{{- include "service-base.pdb" . -}} |
templates/metrics.yaml |
{{- include "service-base.metrics" . -}} |
3. Merge v0.2.0 feature code
Files requiring merge (use noa/issue-1 as base, apply v0.2.0 changes from main):
.github/workflows/ci.yml: Add --path agynio/api/identity/v1 --path agynio/api/authorization/v1 to buf generate command.
Dockerfile: Add --path agynio/api/identity/v1 --path agynio/api/authorization/v1 to buf generate command.
charts/threads/values.yaml: Add IDENTITY_ADDRESS and AUTHORIZATION_ADDRESS env vars.
cmd/threads/main.go: Add identity/authorization gRPC client connections (using .gen/go/ import paths). Use grpc.NewClient for all connections.
internal/config/config.go: Add IdentityAddress and AuthorizationAddress fields.
internal/server/converter.go: Add fmt import, remove participants length guard, replace unspecified status return with panic.
internal/server/server.go: Add identity/authorization clients, SendMessage identity check logic, requireClusterWriter method, use unified pagination functions.
internal/store/messages.go: Add RecipientMode type, update SendMessage to accept recipientMode, add loadAllParticipants, scanUUIDs, scanMessagePage helpers.
internal/store/pagination.go: Consolidate to EncodeMessagePageToken/DecodeMessagePageToken (delete unacked-specific versions).
internal/store/store.go: Add loadParticipantsByThreadIDs batch function.
internal/store/threads.go: Use batched participant loading in ListThreads.
devspace.yaml: Add identity/authorization proto paths to buf generate commands.
buf.gen.yaml, buf.yaml, .gitignore: Keep noa/issue-1 versions as-is.
4. Update agynio/bootstrap
After the threads repo is fixed:
- Change
resolved_threads_image_tag in stacks/platform/main.tf to use var.threads_chart_version directly (remove format("v%s", ...)).
- Clear the
threads_image_tag override in stacks/platform/variables.tf (set default to "").
- Update
threads_chart_version to the new release version.
5. Validation
helm dependency build charts/threads && helm lint charts/threads must pass.
go build ./... must pass.
go test ./... must pass.
- The CI workflow must pass on PR.
Notes
- All Go imports must use
.gen/go/ path prefix (not gen/go/).
- Do NOT use
--include-imports in buf generate commands — the buf.gen.yaml v2 managed mode with go_package_prefix handles import mapping automatically.
- The
noa/issue-1 branch's buf.gen.yaml uses managed.enabled: true with go_package_prefix override — this automatically handles all proto packages under buf.build/agynio/api.
Problem
Running the threads service on Mac via bootstrap fails:
The
v0.1.2image tag was built by an old release workflow that only produceslinux/amd64. Mac (Apple Silicon / arm64) has no matching manifest.Root Cause
The repo has two fully diverged branches:
main: Has v0.2.0 features (allow app senders, identity/authorization) but uses an old CI/CD workflow that builds amd64-only images and tags them withvprefix (e.g.,v0.1.2).noa/issue-1(current default branch): Has aligned CI/CD (multi-arch builds per architecture spec), aligned Dockerfile, service-base Helm dependency, DevSpace config, but is missing v0.2.0 features.When
v0.1.2was tagged, both workflows ran — the old one pushedv0.1.2(amd64-only) and the new one pushed0.1.2(multi-arch but withoutvprefix). Bootstrap referencesv0.1.2→ gets the amd64-only image.Additionally, the Helm chart on
noa/issue-1has a lint bug — all service-base includes are in a singleservice-base.yamlfile, which produces invalid YAML when rendered (missing document separators between resources).Required Changes
1. Reconcile branches in
agynio/threadsUse
noa/issue-1as the base (aligned CI/CD, Dockerfile, Helm structure). Apply v0.2.0 feature code frommainon top. Work on themainbranch so it becomes the single source of truth.Files to keep from
noa/issue-1as-is:.github/workflows/release.yml— multi-arch CI/CDREADME.mdgo.mod,go.summigrations/0001_init.sql,migrations/embed.gointernal/db/migrate.go,internal/store/types.goFiles to delete (from
main, not carried forward):Makefilebuf.lockcharts/threads/templates/_helpers.tplcharts/threads/templates/deployment.yaml(custom standalone)charts/threads/templates/service.yaml(custom standalone)charts/threads/templates/serviceaccount.yaml(custom standalone)Files to delete from
noa/issue-1:charts/threads/templates/service-base.yaml(broken single-file pattern)2. Fix Helm chart lint issue
Replace the single
service-base.yamlwith individual template files (one per resource), matching the pattern used byagynio/gatewayandagynio/chat:templates/deployment.yaml{{- include "service-base.deployment" . -}}templates/service.yaml{{- include "service-base.service" . -}}templates/serviceaccount.yaml{{- include "service-base.serviceAccount" . -}}templates/rbac.yaml{{- include "service-base.rbac" . -}}templates/hpa.yaml{{- include "service-base.hpa" . -}}templates/ingress.yaml{{- include "service-base.ingress" . -}}templates/pdb.yaml{{- include "service-base.pdb" . -}}templates/metrics.yaml{{- include "service-base.metrics" . -}}3. Merge v0.2.0 feature code
Files requiring merge (use
noa/issue-1as base, apply v0.2.0 changes frommain):.github/workflows/ci.yml: Add--path agynio/api/identity/v1 --path agynio/api/authorization/v1to buf generate command.Dockerfile: Add--path agynio/api/identity/v1 --path agynio/api/authorization/v1to buf generate command.charts/threads/values.yaml: AddIDENTITY_ADDRESSandAUTHORIZATION_ADDRESSenv vars.cmd/threads/main.go: Add identity/authorization gRPC client connections (using.gen/go/import paths). Usegrpc.NewClientfor all connections.internal/config/config.go: AddIdentityAddressandAuthorizationAddressfields.internal/server/converter.go: Addfmtimport, remove participants length guard, replace unspecified status return with panic.internal/server/server.go: Add identity/authorization clients,SendMessageidentity check logic,requireClusterWritermethod, use unified pagination functions.internal/store/messages.go: AddRecipientModetype, updateSendMessageto acceptrecipientMode, addloadAllParticipants,scanUUIDs,scanMessagePagehelpers.internal/store/pagination.go: Consolidate toEncodeMessagePageToken/DecodeMessagePageToken(delete unacked-specific versions).internal/store/store.go: AddloadParticipantsByThreadIDsbatch function.internal/store/threads.go: Use batched participant loading inListThreads.devspace.yaml: Add identity/authorization proto paths to buf generate commands.buf.gen.yaml,buf.yaml,.gitignore: Keepnoa/issue-1versions as-is.4. Update
agynio/bootstrapAfter the threads repo is fixed:
resolved_threads_image_taginstacks/platform/main.tfto usevar.threads_chart_versiondirectly (removeformat("v%s", ...)).threads_image_tagoverride instacks/platform/variables.tf(set default to"").threads_chart_versionto the new release version.5. Validation
helm dependency build charts/threads && helm lint charts/threadsmust pass.go build ./...must pass.go test ./...must pass.Notes
.gen/go/path prefix (notgen/go/).--include-importsin buf generate commands — thebuf.gen.yamlv2 managed mode withgo_package_prefixhandles import mapping automatically.noa/issue-1branch'sbuf.gen.yamlusesmanaged.enabled: truewithgo_package_prefixoverride — this automatically handles all proto packages underbuf.build/agynio/api.