Skip to content

test(project-engine-client,user-manager-client): spec-verify checksum gate (LLMO-5976)#1777

Open
aliciadriani wants to merge 2 commits into
mainfrom
llmo-5976-spec-verify-gate
Open

test(project-engine-client,user-manager-client): spec-verify checksum gate (LLMO-5976)#1777
aliciadriani wants to merge 2 commits into
mainfrom
llmo-5976-spec-verify-gate

Conversation

@aliciadriani

@aliciadriani aliciadriani commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Spec

LLMO-5976: any re-vendor of the Semrush OpenAPI spec must force a reviewed hash bump.
The vendored spec stays byte-for-byte; if its actual bytes drift from the committed
digest, CI fails until a human reviews the change and bumps the recorded hash in the
same PR. This closes the gap where a silent re-vendor could slip through unreviewed —
the existing overlay-freshness gate (test/overlay.test.js) only pins the CRn
correction overlay against generated types, not the raw vendored bytes.

Implementation plan

Existed: both Semrush client packages (project-engine-client, user-manager-client)
already had an overlay-freshness gate pinning corrections against generated types, and
test/foundation.test.js already asserted textual facts about the vendored spec
(basePath, swagger version) — but neither pinned the spec's raw bytes. That was the gap.

Added (smallest shippable version — extends existing files, no new framework, no
new src/mock logic, zero coverage burden):

  • packages/spacecat-shared-project-engine-client/spec/projectengine_swagger_public.yaml.sha256
    — committed digest.
  • packages/spacecat-shared-user-manager-client/spec/usermanager_swagger.yaml.sha256
    — committed digest.
  • A gate describe block appended to each package's test/foundation.test.js that
    hashes the vendored spec bytes (Buffer, not utf-8) and asserts equality against the
    committed digest, plus a self-test proving hashing tampered bytes does NOT match.
  • A doc note in each package's CLAUDE.md next to the "spec is never edited" line.

The vendored specs remain byte-for-byte unchanged.

CI integration point: runs as a normal Mocha test under each package's npm test
(c8 mocha), which the root .github/workflows/main.yaml Test job already invokes on
every PR via the shared lint-test-coverage composite action. No new workflow, no new
npm script — same path as every other unit test.

Verification:

  • lint clean on both packages.
  • npm test -w packages/spacecat-shared-project-engine-client — 230 passing, 100%
    stmts/branches/funcs/lines.
  • npm test -w packages/spacecat-shared-user-manager-client — 167 passing, 100%
    stmts/branches/funcs/lines.
  • Confirmed the gate bites: appended a byte to the vendored spec, gate failed with a
    "vendored spec drifted" message, reverted.

Cut as speculative:

  • No standalone spec:verify npm script — redundant with the CI-run Mocha test and
    would carry its own coverage burden.
  • No checksum of the generated types.ts or the overlay — the overlay gate already
    guards corrections, and types.ts derives from the spec this gate now pins.
  • No shared cross-package helper — two ~15-line blocks beat a new coverage-tracked
    module for two call sites.

Note: /create-pr skill was not available in this session; this PR was opened directly
via gh pr create with the body manually structured to match the unified template shape.

🤖 Generated with Claude Code

… gate (LLMO-5976)

Commit a SHA-256 of each vendored Semrush swagger beside the spec and verify it
in test/foundation.test.js (runs in CI via `npm test`). Any re-vendor changes the
bytes and fails CI until a human reviews the diff and bumps the recorded hash in
the same PR, so silent spec drift is impossible — a re-vendor is inert until the
hash is bumped.

The vendored specs are untouched (byte-for-byte). Includes gate self-tests
(passes on match, fails on a tampered byte). Documents the mechanism in each
package CLAUDE.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

This PR will trigger no release when merged.

@MysticatBot MysticatBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @aliciadriani,

Verdict: Approve - clean, well-scoped checksum gate with no blocking issues.
Complexity: LOW - small diff, single concern, no risk signals.
Changes: Adds SHA-256 checksum verification gates to both vendored Semrush OpenAPI specs, preventing silent re-vendor without human review (6 files).
Note: Recommend a human read before merge - this change modifies package-level CLAUDE.md files (architectural documentation). The bot review is a complement to, not a replacement for, a human read here.

Non-blocking (3): minor issues and suggestions
  • nit: No .gitattributes rule guarantees byte-stable checkouts for the vendored YAML specs. If a contributor has core.autocrlf=true, the spec could check out with CRLF, producing a hash mismatch that looks like drift but is just a line-ending difference. Consider spec/*.yaml eol=lf in each package or at the repo root.
  • suggestion: The two test implementations are identical except for file paths. If a third vendored spec adopts this pattern, extract a shared helper (e.g., makeChecksumGate(specPath, checksumPath)) to avoid copy-paste drift.
  • nit: The "detects a byte-for-byte mismatch" test asserts a property of SHA-256 itself (different inputs produce different outputs), not a property of the gate logic. It has documentation value but cannot meaningfully fail unless createHash is broken.

Note: CI checks are currently pending.


Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 1m 10s | Cost: $3.16 | Commit: 91266f112758d3805d45dbf60e9b1a3016edc7fc
If this code review was useful, please react with 👍. Otherwise, react with 👎.

@MysticatBot MysticatBot added ai-reviewed Reviewed by AI complexity:low AI-assessed PR complexity: LOW needs-human-review labels Jul 6, 2026
aliciadriani pushed a commit that referenced this pull request Jul 16, 2026
Two follow-on lines drifted since the ADR's 2026-07-06 date:
- LLMO-5976 (spec-verify gate) shipped via #1811, not #1777 (#1777 is still open).
- LLMO-5979 (request timeouts) has since shipped in #1819 (was "in progress / open").

Docs-only; no decision change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
aliciadriani added a commit that referenced this pull request Jul 16, 2026
…#1781)

## Spec

LLMO-5975: agree the ownership boundary for the shared Semrush client
before the facade
build-out (LLMO-5977) lands, so subsequent PRs don't re-litigate it.

**Boundary decided:**
- Shared client owns transport: IMS Bearer auth, retries/backoff,
request timeouts, a
  typed error taxonomy.
- Consumers own: error→HTTP translation, caching, redaction.
- Test: is it true for every consumer (→ shared) or specific to one (→
consumer)?

**LLMO-5980 disposition:** investigation confirmed transport behavior
has already
diverged between spacecat-shared's client and spacecat-api-service's
hand-built
Serenity transport (shared has retry/backoff, api-service has none).
That divergence
is closed directly via a targeted retry-parity fix in api-service
(tracked separately,
not gated on this ADR). Migrating api-service onto the shared client
itself is recorded
as "revisit deliberately" — not funded now, not closed as a non-goal.
It's a deliberate
future call, sequenced after the facade exists, not something the
resilience gap should
stampede.

## Implementation plan

- Adds `docs/adr/0001-shared-semrush-client-ownership.md` — status
Accepted, starts a
`docs/adr/` practice in this repo (previously no ADR file/directory
existed anywhere
in spacecat-shared; tickets were tracked purely via inline external Jira
links).
- No code changes. Doc-only PR.
- Follow-on work referenced in the ADR: LLMO-5977 (facade, gated on
this), LLMO-5978+5979
(typed errors + timeouts, one combined hardening PR), LLMO-5980
(deferred), LLMO-5976
  (spec-verify CI gate — independent, already shipped in #1777).

---------

Co-authored-by: Alicia Adriani <aadriani+adobe@adobe.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-reviewed Reviewed by AI complexity:low AI-assessed PR complexity: LOW needs-human-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants