Skip to content

feat(moduleauthority): expose gateway transport and audit declarations - #32

Merged
antoinetoussaint-byte merged 4 commits into
codefly-dev:mainfrom
gael-obin:feat/gateway-audit-facade
Oct 10, 2026
Merged

antoinetoussaint-byte merged 4 commits into
codefly-dev:mainfrom
gael-obin:feat/gateway-audit-facade

Conversation

@gael-obin

@gael-obin gael-obin commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Expose Client.DeclareAuditEventTypes through the existing authenticated module-authority RPC, with public aliases for its declaration types and enum constants. Existing direct Accounts authority clients can declare without changing transports. NewGatewayAuthority separately opts into a host-provided binary-protobuf Connect bridge, rejects simultaneous direct configuration, blocks redirects and has no fallback.

Declarations use Credentials.Prefix, the existing cached module capability and the existing refresh-once helper. The host retains namespace ownership and schema-compatibility decisions; the SDK preserves the complete schema and wrapped errors. Existing direct and mint-only constructor behavior is unchanged. No generated bindings or SOURCE.txt pins change. Main now contains PR #28; its emission implementation and tests are preserved unchanged, with declarations in separate files.

Maintainer-side review and fixes were done by Antoine's coordinator worker.

Fix or hack

Fixes at the SDK owner: declaration/transport facades and contract tests, including full schema/PII/enum preservation over both transports, cached proof reuse, bounded refresh, refusal codes/details, broker failure, mint-only rejection, absent-bridge behavior and a valid ambiguous-transport rejection fixture. Main's golang.org/x/tools v0.52.0 fixes Go 1.27.2 export-data loading in the API-boundary gate; its walker and negative fixtures remain intact. No stopgap or second declaration mechanism is introduced.

Documentation updated in README.md (startup example, transport selection and errors), AGENTS.md (authority surface; retained main's tooling guidance) and CHANGELOG.md (new public APIs).

Validation

  • Go 1.27.2: go build ./..., go vet ./..., go test ./..., go test -race ./... and the repository's gofmt gate pass, including API-boundary and agent-context tests. There is no separate lint/Makefile target.
  • Buf 1.73.0 with the pinned generation template reproduces gen/ byte-for-byte from the recorded host source commit.
  • Mutations that change the owner, strip the schema, swallow declaration errors or remove the transport-selection guard each make a test fail; restoring the implementation passes. The original tests missed the latter three.
  • A scratch v0.0.2 accounts consumer builds against both that tag and this change without source edits. Existing moduleauthority tests also pass; the tag predates that package.
  • origin/main at 7fe05b85970956d74fa3b7122ac1874d30a37f7d is merged into this branch by bec5e5a97382616845a97bda7edffc794f095461. Conflicts were resolved without changing main's emission implementation/tests or downgrading its tooling. No rebase or force-push.
  • Final-head hosted CI: https://github.com/codefly-dev/saas-sdk-go/actions/runs/38093295813 — both test and gen-drift passed on bec5e5a97382616845a97bda7edffc794f095461. The complete local walk and all four mutation checks also passed again after merging main.

Review and mutation evidence: #32 (comment)

Not verified

No deployed gateway bridge or downstream application integration was exercised. The explicitly selected host must expose each requested bridge procedure; generated clients do not establish host support. The tag compatibility check covers the existing accounts facade, not unrelated generated-API removals already documented on main. No GitHub PR merge, tag or release was performed by this worker; the coordinator owns the upstream merge and downstream pin handoff.

Final review and coordinator handoff: #32 (comment)

The fork-only head currently returns unknown revision through the upstream Go module path, including with a fresh cache and GOPROXY=direct. After merging, the coordinator must verify and hand downstream the resulting upstream commit.

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

@gael-obin — heads-up: I'm taking this PR to merge. obin-ai/module-record-store#115 needs moduleauthority's audit emission (#28) and declarations (#32) in an upstream commit Go can fetch; today it pins 278a7a6, which exists only on your fork. A worker will review this PR, merge main into its branch (no rebase or force-push), fix what the review finds, and post the review here. I'll merge once CI is green. If you'd rather land it yourself, or something here shouldn't go upstream, say so on this PR.

@antoinetoussaint-byte

antoinetoussaint-byte commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Maintainer review of saas-sdk-go PR #32

Reviewed head: 0d5d8c3dcdf9c1fb289191d32e6227bc9de03da4.
Reviewed base (origin/main): a7b6e72cbd9d9aaa70831b6488fa867feaded007.

Phase 1 was completed before changing the PR branch, in a full, non-shallow clone at the exact head. Diagnostic mutations were confined to that scratch clone and restored. The open work inventory was checked; PR #28 remains separate and is not included in these fixes.

  1. High / P1 — The required API-boundary gate cannot load Go 1.27 export data. go.mod:10 pins golang.org/x/tools v0.49.0, while go.mod:3 requires Go 1.27. With Go 1.27.2, go build ./... and go vet ./... pass, but go test ./... fails in all three internal/apiboundary tests: export data version 5 is greater than maximum supported version 4. This is inherited from the base, but blocks this PR's required verification. In the scratch clone, upgrading only x/tools to v0.50.0 makes go test -count=1 ./internal/apiboundary pass; restoring v0.49.0 reproduces the failure. Remediation: consume the upstream x/tools v0.50.0 export-reader fix, update its checksums, document the tooling requirement, and run the complete walk. Keep the boundary walker and its negative fixtures intact.

  2. Medium / P2 — Declaration tests allow the schema to be silently stripped. moduleauthority/audit_test.go:17 checks only the prefix and first event name. Replacing each outbound declaration with &ModuleAuditEventTypeDeclaration{Type: typ.Type} drops descriptions, fields, visibility, enum values and PII metadata, yet go test -count=1 ./moduleauthority still passes. This also mutates the caller's input, which the test does not detect. A separate wrong-prefix mutation does fail the existing test, confirming it is exercised. Remediation: assert the complete serialized declaration against an independent snapshot, with multiple event types, enum values and PII fields; verify caller input remains unchanged. Exercise both direct gRPC and the gateway Connect transport, including refresh/retry.

  3. Medium / P2 — Declaration error and authority semantics have no regression coverage. moduleauthority/audit_test.go:9 exercises only success; moduleauthority/host_fake_test.go:356 always accepts an authenticated declaration. Changing DeclareAuditEventTypes to discard its wrapped error and return nil leaves the entire moduleauthority test suite green. Thus the tests do not protect startup failure on a refused declaration, a missing authority seam, or a failed credential mint. The gateway tests exercise exchange, not declarations or their refusals. Remediation: add real-wire declaration tests for preserved Connect error codes/details, no retry on permission/schema refusals, exactly one refresh on Unauthenticated, broker failure before authority dispatch, mint-only ErrNoAuthority, and an unavailable gateway bridge without fallback. Repeat the mutations and require red tests before restoring the correct implementation.

The production declaration method correctly reuses callAsModule, the existing generated RPC, the module prefix from Credentials, and the existing credential cache/refresh mechanism. It adds no separate registration mechanism or product-specific policy. The source host at the recorded proto commit exposes DeclareAuditEventTypes on its direct authority endpoint and owns namespace admission, compatibility and visibility rules. No new generated type is missing a facade alias or enum constant. No existing exported signature or direct/mint-only constructor behavior changes in this PR.

A scratch consumer using the v0.0.2 accounts facade (New, Audit, QueryAuditLog, and Connect options) builds both against that tag and against the PR head without source changes. The tag predates moduleauthority; this is a representative compatibility check, not a claim that unrelated, previously documented generated-API removals between the tag and main are compatible.

Buf 1.73.0 regenerated the recorded module-saas-starter@21f139ee433695ae2129899f265c59b99f6661af proto with this repo's pinned template into scratch; diff -r against committed gen/ is empty. No source pin or generated files need changing. The pending fork run 37979973167 was approved as repository admin; its gen-drift job has passed and its test job is still running at review publication.

Not verified in Phase 1: a deployed host gateway bridge or downstream application integration. The source pinned by this SDK does not itself establish gateway-bridge support; the explicit constructor's host-support precondition must remain documented. The full local walk stops at the API-boundary failure above, so a complete race pass is still required after the fix. The added code and fixtures contain no downstream product-specific vocabulary; the PR body will be rewritten around the generic SDK contract.

  1. Medium / P2 — Ambiguous-transport rejection test passes for unrelated missing seams. Supplemental review of the original head during Phase 2: moduleauthority/gateway_test.go:61 supplies only a direct address, omitting both Gateway and InternalToken. Disabling the explicit NewGatewayAuthority ambiguity guard at moduleauthority/gateway.go:20 still lets the original complete moduleauthority suite pass, because New rejects the incomplete fixture anyway. Remediation: give the test otherwise-valid seams and credentials, then require ErrInvalidSeams without any host request; disabling the ambiguity guard must make that test fail.

Hosted CI update: the approved original run subsequently passed both jobs. Its logs show Go 1.27.0 on Linux; the independently reproduced export-reader failure in finding 1 is on local Go 1.27.2. A green original hosted run does not cover that local toolchain failure.

Proceeding to fix all four findings on the existing fork branch, merge origin/main without rebasing, and obtain green local and hosted checks. The coordinator retains merge and release authority.

@antoinetoussaint-byte

antoinetoussaint-byte commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

The initial green handoff was reopened when PR #28 landed on main. The conflict is resolved by merging main into this branch; all checks passed again.

The final reviewed head is bec5e5a97382616845a97bda7edffc794f095461. See the final review result and coordinator handoff.

@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Maintainer review result for saas-sdk-go PR #32

Ready for the coordinator to merge at head bec5e5a97382616845a97bda7edffc794f095461.
Base: 7fe05b85970956d74fa3b7122ac1874d30a37f7d.
Original reviewed head: 0d5d8c3dcdf9c1fb289191d32e6227bc9de03da4.
Original reviewed base: a7b6e72cbd9d9aaa70831b6488fa867feaded007.

All four findings in the maintainer review are resolved. Antoine's coordinator worker pushed the fixes normally to gael-obin/saas-sdk-go:feat/gateway-audit-facade.

PR #28 landed externally while the first green handoff was being published. This worker then merged the new origin/main into this branch, resolved the conflicts, and repeated the complete verification. Merge commit bec5e5a97382616845a97bda7edffc794f095461 has parents 83b5d5621a791314757c1b0edae6d444de7c979c and 7fe05b85970956d74fa3b7122ac1874d30a37f7d. Main's audit emission implementation and tests are unchanged; declarations now live in separate audit_declarations.go / audit_declarations_test.go files. The final head contains the current base. No rebase or force-push was used.

  1. Resolved — High / P1, Go 1.27.2 API-boundary loading (go.mod:10). The merged result retains main's x/tools v0.52.0, which includes the upstream export-reader fix. The original diagnosis proved v0.50.0 sufficient before the newer fix landed on main. The three API-boundary tests now pass, including their negative fixtures; the walker was not weakened. Restoring v0.49.0 in scratch reproduced export data version 5 is greater than maximum supported version 4. AGENTS.md and CHANGELOG.md document the requirement. The original hosted run used Go 1.27.0, which explains why its success did not cover this local failure.

  2. Resolved — Medium / P2, unprotected declaration schema (moduleauthority/audit_declarations_test.go:114). Real gRPC and binary-protobuf Connect tests compare the entire decoded request to an independent protobuf snapshot: multiple types, descriptions, fields, enum values, visibility and PII flags. They verify unchanged caller input, one cached module mint across calls, and only the module capability/perimeter credential on authority calls. Refresh tests at line 140 check that the same schema survives a rejected token and a single replacement. Wrong-owner and stripped-schema mutations now fail on both transports.

  3. Resolved — Medium / P2, declaration refusal coverage (moduleauthority/audit_declarations_test.go:167). Tests preserve host error codes, messages and typed details through the facade; PermissionDenied, InvalidArgument, FailedPrecondition and Unavailable produce one call, while repeated Unauthenticated produces exactly two. Tests also cover broker refusal before authority dispatch (line 202), mint-only ErrNoAuthority before any request (line 217), and a missing bridge with no retry/fallback (line 235). Swallowing the declaration error now makes these tests fail. The SDK continues to use the existing callAsModule mechanism and host admission rules.

  4. Resolved — Medium / P2, ambiguous-transport test (moduleauthority/gateway_test.go:61). The fixture now supplies an otherwise-valid gateway, direct authority endpoint, credentials and perimeter token. Disabling the explicit constructor guard now fails the test with got <nil>, want invalid seams, instead of passing because another seam was missing. The test also checks that rejection sends no request.

All four intentional mutations were repeated against the final merged tree and restored; the moduleauthority suite passed afterward. The implementation remains generic: examples use example.item.*, and the PR introduces no downstream product policy, second declaration registry, endpoint fallback, generated-file edits or new source pin.

Validation on the final change:

  • Go 1.27.2: go build ./..., go vet ./..., go test ./..., and go test -race ./... pass, including API-boundary and agent-context gates. Every non-testdata Go module is covered (the root is the only one).
  • The repository's handwritten-code gofmt gate and git diff --check pass. There is no separate lint configuration or Makefile target.
  • Buf 1.73.0, the pinned plugins, and recorded host source 21f139ee433695ae2129899f265c59b99f6661af reproduce gen/ byte-for-byte. Neither gen/ nor SOURCE.txt changed.
  • A scratch accounts consumer built at the current tag v0.0.2, then built unchanged against the reviewed/fixed SDK. The tag predates moduleauthority; existing moduleauthority tests pass, and this PR changes no existing exported signature. The README declaration example also compiles.
  • Final-head CI run 38093295813 passed both test and gen-drift. The original and first-fix fork runs were approved with the admin account; the final merged-head run started without another approval gate.
  • README.md, AGENTS.md and CHANGELOG.md are updated. The PR body names these files, classifies the changes as owner fixes, and includes the requested maintainer-worker attribution. The worktree is clean.

Not verified: a deployed gateway bridge or downstream application integration. The selected host must expose each requested bridge procedure; the existing direct authority endpoint supports declarations independently. The representative tag consumer check does not reverse unrelated generated-API removals already documented on main.

The fork-only head is not yet fetchable under the upstream module path. GOPROXY=direct go mod download github.com/codefly-dev/saas-sdk-go@bec5e5a97382616845a97bda7edffc794f095461 returned unknown revision with a fresh module cache. The earlier fork-only head also failed through the default proxy path. No fork replacement or other workaround was installed in a consumer repository.

Coordinator: merge PR #32 at the reviewed head above, verify Go can fetch the resulting upstream commit (a squash may change its SHA), and provide that upstream pin to the waiting consumer. PR #28 is already on main and its work is preserved. This worker has not merged any GitHub PR, tagged, released, opened issues, or changed PR #28.

@antoinetoussaint-byte
antoinetoussaint-byte merged commit 0e4e6e7 into codefly-dev:main Oct 10, 2026
2 checks passed
@antoinetoussaint-byte

Copy link
Copy Markdown
Contributor

Merged at 0e4e6e7 (reviewed head bec5e5a, CI green). Go fetches it: go mod download github.com/codefly-dev/saas-sdk-go@0e4e6e78f013 → v0.0.3-0.20261010230102-0e4e6e78f013. obin-ai/module-record-store#115 pins this commit. Thanks @gael-obin.

@antoinetoussaint-byte

antoinetoussaint-byte commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

lazybox has finished working on this. codex (Astra) held it from 2026-10-10 22:41 UTC until 2026-10-20 00:41 UTC. The working label has been removed; this comment is the record.

claim detail
Lazybox-Claim-Device: effacd542b611010656e
Lazybox-Claim-Session: 166fc72c75
Lazybox-Claim-Workspace: github-codefly-dev-saas-sdk-go-32
Lazybox-Claim-Agent: codex
Lazybox-Claim-Model: Astra
Lazybox-Claim-Started: 2026-10-10T22:41:09Z
Lazybox-Claim-Heartbeat: 2026-10-20T00:41:17Z
Lazybox-Claim-Expires: 2026-10-19T16:49:29Z
Lazybox-Claim-Released: 2026-10-20T00:41:17Z

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.

2 participants