fix(egress-audit): move the harness to @ever-co/connect-tools 1.0.0-rc.8

Merged
EV
13d ago
+142-62

Why

The Egress audit workflow on develop has been red since #11567 (run 41327796768). The job "egress-audit inputs" fails at "The list of outbound calls is the pinned contract's" because #11567 moved ever-connect/ever-stats to @ever-co/connect-* 1.0.0-rc.8 and the connection now makes rows 14, 19, 20 and 22, but the audit harness still pinned rc.7. #11567's handover listed this as a follow-up. #11618 already fixed the import-boundary part.

What changes

  • tools/egress-audit/package.json and package-lock.json: @ever-co/connect-tools goes from 1.0.0-rc.7 to 1.0.0-rc.8, eslint from 10.12.0 to 10.14.0 and @typescript-eslint/parser from 8.71.2 to 8.72.1, both latest. typescript stays at ~6.0.3: parser 8.72.1 only accepts typescript >=4.8.4 <6.1.0, which rules out 7.x. The lockfile was regenerated with npm 11 and only those four packages changed.
  • tools/ever-platform/outbound-calls.config.json: modules.connect now includes rows 14, 19, 20 and 22. I checked each request in packages/plugins/ever-connect/src:
    • 14: instances.oidcClient.request/get in ever-id-login.handler.ts
    • 19: instances.personLinks.create/remove in person-link.reporter.ts
    • 20: instances.ack in person-requests.handler.ts
    • 22: identity.resolve in ever-id-login.handler.ts
  • tools/ever-platform/outbound-calls.md: regenerated with --write. The rows move from "not made" to "every call", and the contract version is now rc.8. The published copy in ever-co/ever-gauzy-docs (website/docs/ever-platform/outbound-calls.md) still has to be updated to match.
  • tools/egress-audit/egress-audit.config.json: rows 14, 19, 20 and 22 are removed from every_trigger_exclude_rows. The outbound-calls check requires that list to equal the "not made" table.
  • outbound-calls.config.json gauzy_rows.14 (review follow-up): row 14's "How often" gives Gauzy's own schedule. A request that did not go through is sent again after 30 s, the wait doubling up to an hour. The client is read at least 5 s later, then with the wait doubling up to 5 min.
  • patch-mock-clock.mjs: rc.8 has the same line in MockState.bucket as rc.7, so the same patch still applies. PATCHED_VERSIONS now also lists 1.0.0-rc.8. Tested locally: the patch applies, a second run reports it already applied, --check passes, and patch-mock-clock.test.mjs passes 4/4 against the rc.8 mock.
  • adapter.mjs (every_trigger): two new triggers, both driven by controls the rc.8 mock already has:
    • Row 14: /__mock/consent sets ever_id_login to wait for the operator, and the operator accepts through POST /api/ever-connect/integrations/ever_id_login/accept. The connection then requests its sign-in client and polls it. The mock allows a consent to enable the "coming soon" ever_id_login. Ever Platform only takes an exact https callback, so this mode sets ZITADEL_CALLBACK_URL=https://gauzy.example.com/api/auth/zitadel/callback. That URL only travels as request data, and the sign-in plugin stays off.
    • Row 20: /__mock/person-request puts a deletion request on the event feed, and the installation answers it with POST /v1/instances/me/ack.

Runtime gap: rows 19 and 22 (needs a decision)

every_trigger cannot trigger rows 19 (person links) or 22 (identity resolution) yet:

  • Both need a person who signed in with Ever ID through the installation's own sign-in client.
  • The rc.8 mock platform has no Ever ID issuer to sign in at. It serves no discovery, authorization, token or JWKS endpoints.
  • Its issuer name https://mock-platform.test does not resolve on the sealed networks. Any sign-in attempt would itself be a DNS lookup outside the compose services, which the audit counts as a violation.

The module does make both rows: its README request table and the outbound-calls list name them. So they cannot honestly stay in every_trigger_exclude_rows, and the harness does not let a product redefine every_trigger.

As a result, every_trigger will report "row 19/22 was required but never called" (exit 1) until one of these happens:

  • (a) @ever-co/connect-tools ships a mock Ever ID issuer reachable on the sealed network, or
  • (b) we add a way to declare rows that a module makes but the audit cannot trigger. For example, a key in outbound-calls.config.json that the check adds to the excluded set, together with a reason.

This PR adds neither. Both are documented in tools/egress-audit/README.md ("Modes").

Separate, pre-existing issue

The daily run 41281388492 on 2026-11-01 already failed off, loaded_off, positive_stats and connect_off_sign_in_on. Each failed in the browser leg on dom_never_allowed: /pages/settings/whats-new links https://docs.gauzy.co/. That link comes from the web app image, not from this change, and this PR does not touch it.

Tests

All run locally with Node 24 and npm 11, on a full checkout:

  • the ui-routes --check route-list check passes (319 routes);
  • check-baseline-shrink --base origin/develop and check-baseline-rewalk.mjs pass;
  • static-hostnames.mjs --check-shrink passes;
  • node --test passes for check-baseline-legal (10/10), patch-mock-clock (4/4), static-hostnames (8/8), import-boundary (6/6, run with ESLINT_PREFIX and EVER_BOUNDARY_ESLINT_REQUIRED=true), outbound-calls (4/4) and check-private-deps (8/8);
  • check-private-deps.mjs passes;
  • outbound-calls.mjs --check reports: ok (contract 1.0.0-rc.8; 17 rows made, 8 not made).

The workflow does not run on PRs into develop. I dispatched it on this branch to run the docker jobs: https://github.com/ever-co/ever-gauzy/actions/runs/41330846134 and again at fe58caf035 (https://github.com/ever-co/ever-gauzy/actions/runs/41332011402). Both runs used demo images built from d5c974b874 (#11567):

  • inputs, static-bundle, off_env_file, entitlement_ladder (on the patched rc.8 mock) and control: green.
  • every_trigger: exit 1, and only because rows 19 and 22 were never called. Rows 14 (POST and GET) and 20 were called, with no faults and no DNS or connection violations.
  • off, loaded_off, positive_stats and connect_off_sign_in_on: each has one dom_never_allowed (docs.gauzy.co on /pages/settings/whats-new), the pre-existing issue above.

🤖 Generated with Claude Code