Skip to content

feat: the install step, verified by the authority's step verifier - #80

Open
antoinetoussaint-byte wants to merge 3 commits into
mainfrom
feat/installation-step-receiver
Open

antoinetoussaint-byte wants to merge 3 commits into
mainfrom
feat/installation-step-receiver

Conversation

@antoinetoussaint-byte

@antoinetoussaint-byte antoinetoussaint-byte commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

The solution-side receiver for a pending installation's setup. It runs on the existing listener and is verified only by the Authority's dedicated installation-step verifier. Full evidence: .lazybox/artifacts/installation-receiver/report.md in the runtime73 worktree.

What

Request. POST /_codefly/installations is SaaS's existing delivery path and Authority's InstallationStepHTTPMethod.

  • Exactly one x-codefly-work-context.
  • The body is exactly {installation_id, organization_id, revision}. A scope or any other member is refused 400.
  • x-codefly-installation-id and -revision must equal the body.

Verification. The runtime calls AuthorityService.Check at that exact method, with its own delivered principal as the audience and never in advisory mode. Before the step runs or any cached ack is answered, the verified context must match:

  • organization and tenant;
  • the installation seal and its revision;
  • the audience.

It must also have a non-empty task_id, no actor chain, and the sole scope installations:install:[id].

The step. OnInstall(func(ctx, Installation) error) gets Installation{ID, OrganizationID, Revision, OperationID} and no Gateway. With no OnInstall the answer is 409, never 204. An explicit no-op acknowledges.

Once-ledger. Keyed by (installation, revision, consent operation), per process. It answers only after a fresh successful Check on every request.

Answers.

  • 204: done.
  • 409 {reason}, with one generic reason when the authority refused:
    • RefuseInstall;
    • PermissionDenied, InvalidArgument, Unauthenticated or NotFound;
    • a refusal returned beside the context;
    • a mismatch;
    • no declared step.
  • 401: no single credential was carried.
  • 400: a malformed body or carriers.
  • 503: FailedPrecondition, Canceled, DeadlineExceeded, Unavailable, Internal, or a failed step.

Classification

Fix, at the owner of the behaviour. Authority verifies, and the runtime compares and runs the step. Not revived from the deleted legacy handler: success from a parsed carrier alone, a nil-step acknowledgement, or the step acting under the carried capability.

Reuse

Reused: SaaS's existing delivery path and statuses, the existing Check RPC and hostAuthority, and the deleted handler's bounded once-ledger and sanitizer. There is no new RPC, pin or proto change. Not added: a runtime generation slot, since Authority checks generation through its signed binding and current state.

Owner contract and qualification

Authority. Authority10882's contract is at codefly-dev/authority 21ce6d9 (tree 86e128ec), which includes the step verifier and its maintained generation. This PR selects authority-client/go v0.1.1-0.20261029092314-21ce6d9284ed, the confirmed coordinate. hop is unchanged.

Receiver against Authority's real local plugin at 21ce6d9. Both in process and as the installreceiver process booted through Serve and reached over HTTP:

  • 409 for a wrong audience, a tampered credential, another revision/org/installation, and no step;
  • refuse → 409, fail → 503;
  • ack → 204, then 204 on redelivery, recorded once;
  • 503 after activation.

Paired crossing, SaaS10887, PASS. TestCanonicalCombinedInstallQueueThroughRuntime covers native PostgreSQL → combined review/install → SQL claim → Accounts HostAuthorityServer.Check → this receiver at e6809f5 as a process → finish → final transaction:

  • ack → active;
  • refuse 409 and fail 503 → pending;
  • a cached-ACK redelivery → 204;
  • post-active → 503.

Evidence: runtime73's .lazybox/artifacts/installation-receiver/HANDOFF.md, and SaaS's install-final-qualification/canonical-queue-receiver-3.log.

Docs

README.md ("The install step"), AGENTS.md and CHANGELOG.md.

Tests

installation_test.go runs against a stand-in authority. Nine production mutations each turn it red; the list is in the artifact. Out of tree, a scratch go.work ran the receiver against Authority10882's frozen uncommitted candidate, using its real local AuthorityService plugin and a real IssueInstallationStep. Results:

  • 204, with the step run once on the verified facts;
  • every mismatch refused before the step runs;
  • a redelivery answered from the ledger after a fresh Check;
  • after core.Install activated, the same credential got 503 (FailedPrecondition), and the cached 204 was not replayed.

go test -race ./..., vet and gofmt are green.

Not verified

  • No deployed gateway, cell or live composition. SaaS's crossing used the gateway's request shape from a test.
  • The receiver binary's hash is not recorded in SaaS's artifacts.
  • Consumers adopt this by pinning v0.0.17-0.20261029092559-e6809f537977. Product117 consumes it locally before merge.

🤖 Generated with Claude Code

antoinetoussaint-byte and others added 3 commits October 28, 2026 23:51
The host delivers a pending installation's setup to POST /_codefly/installations,
as its existing gateway delivery does. The runtime served nothing there since
e80369a deleted the saas-mode handler, which trusted a parsed carrier,
acknowledged a nil step and let the step act under the carried capability.

Now the authority verifies the step: the runtime asks Check at exactly
POST /_codefly/installations, which the authority routes to its dedicated
installation-step verifier, never advisory. The body and the installation
carriers must name exactly the organization, installation and revision
verified, with a consent receipt and only installations:install on that
installation. The step receives those facts (Installation, now with Receipt)
and no Gateway; a solution with no OnInstall is answered 409, never 204. One
(installation, revision, receipt) runs once per process, and a repeat is
verified before a remembered acknowledgement answers it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… 409 generically

Agreed with Authority10882 and Root10879:

- The body is exactly {installation_id, organization_id, revision}. A scope, or
  any other member, is refused 400; the step credential verifies nothing else.
- A refusal answered beside the verified context is a refusal, since this check is
  never advisory.
- Unauthenticated joins PermissionDenied/InvalidArgument/NotFound as 409, with one
  generic reason. The authority's own reason is logged and never crosses into the
  host's job history. Cancelled and timed-out calls stay 503.
- Installation.Receipt is renamed OperationID: the verified task id is the consent
  operation, not the whole receipt, whose intent, generation and digest the
  authority checks.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…step handoff

Authority's installation-step source and its maintained generation are pushed
at codefly-dev/authority 21ce6d9 (tree 86e128ec). The installation-step
receiver checks setup steps through AuthorityService.Check at the reserved
POST /_codefly/installations method; this selects the generated client that
documents that reserved Check, so the runtime builds against the client
generated from the source it is qualified with. No new RPC or field is used,
and hop stays at its existing pin.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@antoinetoussaint-byte
antoinetoussaint-byte marked this pull request as ready for review October 29, 2026 10:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant