Repository navigation
Hand a solution page its viewer organization's installation - #1036
Merged
Merged
Conversation
…llation The authority's entitlement answer already carried each installation id, and the gateway dropped it, so a solution page could not learn which installation it acts in. An agent module binds every assistant turn to one, so a consuming solution had to ask a person to paste a UUID. The gateway's /solutions/_entitlements entries now carry installationId. GET /api/solutions/<id>/installation resolves the verified viewer organization's active installation of the routed solution through the navigation's own entitledSolutions join (404 when unregistered or not entitled), the outlet reads it with the viewer's session, and SolutionBinding gains an optional installationId. A page never names one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p test names generic SolutionBinding gained installationId, so saas-ui publishes changed bytes: the kit moves to 0.12.6 with @codefly-dev/ui and the frontend pins. The route test named real solutions, which the boundary gate refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte
enabled auto-merge
October 7, 2026 20:04
antoinetoussaint-byte
added a commit
that referenced
this pull request
Oct 7, 2026
…1013) main moved five commits under this branch — #953 (the solution/module lifecycle), #1029, #1034, #1036 and release v0.0.93 — which left the PR unmergeable. An unmergeable PR schedules NO checks, so "0 failing checks" was zero checks rather than a green run; nothing had graded the last four commits. Three things the merge had to settle: - **A migration number collision.** #953 added migrations 20 through 29, and this branch had taken 20. Two files at one version refuse the whole lineage at runtime-init ("migration version 20 has two down files"), which is why the dependency boot failed rather than any test. Renumbered to 30; every version is now unique. Migration numbers are renumbered, never reused. - **pkg/business/service_test.go** — main wired the policy log into the test service beside the cipher wiring this branch replaced. Both belong, so both are kept. - **pkg/infra/export_test.go** — main added ExecAsControlPlane and this branch added the enveloped-column bridge, at the same place and independent of each other. Both kept. The generated control-plane call-site allowlist was REGENERATED rather than trusted as a text merge: it auto-merged cleanly, which proves nothing about whether it still matches the code on both sides. **Not verified, and unverified is not working:** the database-backed suites did not run after the merge. The local Postgres lineage is dirty at version 23 — one of main's new migrations, left mid-apply by the boot that failed on the number collision — and the postgres agents serving it are owned by other live sessions on this machine, so resetting it would disturb work that is not mine. Build, untagged `go vet ./...`, the pure suites, the keyservice suite, the accounts root suite and the repository gates are green; the DB suites are CI's to grade, on a clean database. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A solution page now receives its viewer organization's installation from the host, as an optional
SolutionBinding.installationId.Why
An agent module binds every assistant turn to an (installation, intent) pair that it verifies against the host. The host handed a solution page only
solutionId,apiBaseand the token accessors, and an org member has no read from (organization, solution) to installation. So a consuming solution could only run that module's assistants by asking a person to paste an installation UUID. That is self-identification, and a page-chosen installation could be another organization's.The data was already there.
SolutionEntitlementService.ListSolutionEntitlementsreturnsinstallation_idfor every entitled installation; the gateway's/solutions/_entitlementsprojection dropped it. Agreed with the #953 author: resolve it per (viewer organization, routed target), never by alias, never from the page, on main after #953.What changes
solutionEntitlementEntrycarriesinstallationId, copied from the authority answer.SolutionEntitlement.installationIdis parsed (empty when an older gateway does not say) and is part of the projection cache revision.GET /api/solutions/[id]/installation: verified entitlements → the navigation's ownentitledSolutionsjoin over the whole registry →{installationId, healthy}, or404for unregistered and unentitled alike. Registered in the boundary test'sprojectionSurfaces, so it must keep narrowing through the entitlement read.authedFetchand passesinstallationIdto the remote. Undefined while resolving or on any refusal; it never substitutes a value.SolutionBinding.installationId?: string, optional per the binding's own rule (a minor of the host↔remote contract).Classification: fix at the owner (the host decides which installation a viewer acts in). Docs:
module/SOLUTION_REGISTRATION.md(§4, the third projection) andservices/frontend/code/packages/saas-ui/README.md.Verified
go vet ./...andgo test ./...pass; the entitlement test asserts the id travels.tsc --noEmitclean; the solutions,api/solutionsand saas-ui solution suites pass (382 tests), including 5 new route tests (entitled, unentitled, unregistered, older gateway, unauthenticated) and 2 outlet tests (the id reaches the page; a refusal hands none).module/tools(boundary and doc-claim gates) passes.Not verified
ListAvailableSolutions→InstallSolutionwithtarget_id), and a local delivery verb is the open question the feat: the solution and module lifecycle — a static delivered half and a dynamic runtime half (#952) #953 author offered to raise.solution:usegrant gets no installation: the entitlement read returns only granted installations, which is the intended narrowing.🤖 Generated with Claude Code