Keep Shopify operations truthful and releases recoverable - #214
Merged
Conversation
Validate the untouched raw body with Shopify's supported webhook primitive, require a durable Delivery API receipt before acknowledgement, and expose sanitized token health for operators. Constraint: K-food rollout must remain fail-closed and preserve Shopify retry semantics. Rejected: authenticate.webhook for order admission | pinned 1.2.1 source performs offline-session validation after HMAC. Confidence: high Scope-risk: moderate Directive: Keep Delivery API as the final HMAC and durable-inbox authority; retry mode must never acknowledge. Tested: clean npm ci; pinned integrity/source SHA verification; 563 app tests; lint; typecheck; build; public URL guard; three compose configs. Not-tested: live K-food webhook delivery and production metrics are deployment-stage gates.
Reject non-POST admission explicitly and retain the last token failure across later successful syncs so operators can query historical failure evidence. Constraint: Health evidence must stay sanitized and must not alter Shopify SDK internals. Confidence: high Scope-risk: narrow Directive: Do not clear lastFailureAt or lastErrorCode when current token sync returns healthy. Tested: 564 app tests; targeted webhook/token tests; lint; typecheck; build. Not-tested: live K-food traffic remains the deployment-stage gate.
Constraint: Preserve G006 session-free webhook and token-health behavior while consuming the additive server operationalState contract without per-row requests. Rejected: Keep bespoke status badges or infer device progress from GPS | Independent source authority and accessible Pill semantics require one shared pure mapper. Confidence: high Scope-risk: moderate Directive: Keep RouteOperationalStateV1 additive and render absent evidence as Unknown; do not reintroduce prose-separated operational summaries. Tested: app 571 tests; lint; production build; typecheck; public URL guard; main/dev/kfood compose config Not-tested: authenticated browser visual smoke and production deployment
Constraint: Group children are rebuilt from routeGroups while operationalState is enriched on the already fetched routePlans list. Rejected: Fetch operational state per grouped row | It adds N+1 requests and duplicates the server batch contract. Confidence: high Scope-risk: narrow Directive: Preserve the routePlanId join whenever grouped child presentation is rebuilt; never derive device state from GPS. Tested: targeted 17 tests; full app 573 tests; lint; production build; typecheck; public URL guard Not-tested: authenticated browser visual smoke and deployment
Constraint: Shopify publishes no fixed webhook body maximum, so the 5 MiB default is a configurable application safety budget. Rejected: Adopt the RED fixture's 2 MiB value or call request.text() before validation | Neither is an official platform limit and request.text() is unbounded. Confidence: high Scope-risk: narrow Directive: Keep the byte limit ahead of SDK HMAC validation and Delivery forwarding; preserve streaming UTF-8 decoding and never log payload bytes. Tested: targeted 17 tests; full app 579 tests; lint; production build; typecheck; public URL guard; main/dev/kfood compose config Not-tested: production deployment and a live Shopify oversized delivery
Consolidate identical token failure state shaping and replace nested health classification while preserving fail-closed webhook, unknown-health, and legacy optional-field behavior. Constraint: Preserve the verified Shopify remediation behavior exactly Rejected: Redesign admission, receipt, token, or Pill contracts | Those boundaries are grounded and regression-covered Confidence: high Scope-risk: narrow Directive: Keep unknown evidence explicit and webhook admission fail-closed Tested: 579 tests; build; typecheck; lint; public URL guard; main and K-food compose config Not-tested: Production runtime behavior is verified by the deployment story
Constraint: Settings and health endpoints may resolve only the authenticated session shop. Rejected: Global or query-selected health state | it leaks failures across shops. Confidence: high Scope-risk: narrow Directive: Keep token health reads keyed by trusted app and session identity. Tested: Shopify app 582 tests; targeted token sync tests; lint; build; typecheck; public URL guard; compose config. Not-tested: Production deploy, excluded by task.
Constraint: Preserve useful correlation and tenant observability without emitting raw errors, stacks, shop domains, or customer/order data. Rejected: Sanitize arbitrary error strings | Allowlisting stable fields avoids future redaction bypasses. Confidence: high Scope-risk: narrow Directive: Route external operational logs through the safe allowlist and hash shop identities before logging. Tested: 4 hostile log tests; 164 targeted tests; 586 full tests; build; typecheck; lint; public URL guard. Not-tested: Live production log ingestion.
Constraint: Preserve user-visible error behavior while removing raw external values from server and browser logs. Rejected: Redact arbitrary messages in place | allowlisted stable fields avoid bypasses. Confidence: high Scope-risk: moderate Directive: Keep new runtime logs behind allowlisted telemetry; hash authenticated shops. Tested: 10 structural/hostile log tests; 210 targeted tests; 592 full tests; build; typecheck; lint; public URL guard. Not-tested: Live production external log ingestion.
Constraint: Authenticated app loaders must not wait indefinitely on a half-open Delivery API. Rejected: AbortSignal alone | injected fetch implementations may ignore abort and keep the shared in-flight promise pending. Confidence: high Scope-risk: narrow Directive: Keep token exchange deadlines bounded and timeout health free of raw request or shop data. Tested: 21 targeted token/log tests; 594 full tests; build; typecheck; lint; public URL guard. Not-tested: Live production Delivery API half-open connection.
Constraint: Compliance HMAC authentication must receive exact bytes without buffering unbounded unauthenticated payloads. Rejected: Clone then read the request | it duplicates the body and bypasses the shared streaming cap. Confidence: high Scope-risk: moderate Directive: Keep order and compliance admission on the shared 5 MiB default and 10 MiB maximum. Tested: 43 focused webhook/log tests; 597 full tests; build; typecheck; lint; public URL guard. Not-tested: Live Shopify compliance delivery.
Constraint: Server IGNORED receipts are terminal only when explicitly suppressed and duplicate. Rejected: Treat every unknown 200 receipt as durable | arbitrary statuses must remain retryable failures. Confidence: high Scope-risk: narrow Directive: Keep Shopify durable receipt statuses synchronized with the Server terminal contract. Tested: 32 focused webhook/log tests; 599 full tests; build; typecheck; lint; public URL guard. Not-tested: Live redacted-shop webhook delivery.
Keep each target on an immutable commit image and restore verified SQLite state whenever migration, restart, or smoke validation fails. Constraint: Manual EC2 workflow must preserve runtime env files and allow independent target deployments Rejected: Shared-root rsync with a mutable local image | it cannot identify or restore the exact prior release Confidence: high Scope-risk: moderate Directive: Keep current/previous pointer changes after candidate smoke and retain target-scoped locks Tested: 607 Shopify tests; build; typecheck; lint; public URL guard; actionlint; shellcheck; YAML parse; K-food compose override config Not-tested: Live EC2 rollback injection and production/K-food workflow dispatch are deferred to the authorized deployment stage
Constraint: Mandatory Shopify compliance deliveries must be HMAC-verified from the exact bounded raw body without session storage availability. Rejected: authenticate.webhook admission | It couples compliance receipt to offline Admin session refresh and database health. Confidence: high Scope-risk: narrow Directive: Keep compliance webhook admission session-free and acknowledge only durable Delivery receipts. Tested: 601 node tests; focused compliance/store tests; lint; typecheck; build; Shopify SDK source pin; public URL guard Not-tested: Live Shopify compliance delivery in production
Constraint: Deploy retries must remain recoverable across same-SHA builds, partial stops, signals, and legacy first transitions.\nRejected: Mutable rollback tags derived after build | same-SHA rebuilds can replace the only recoverable image.\nConfidence: high\nScope-risk: moderate\nDirective: Keep path validation, rollback snapshot proof, and recovery arming ahead of every remote mutation.\nTested: npm test (616/616); npm run build; npm run typecheck; npm run lint; npm run check:public-urls; actionlint; shellcheck; YAML parse; git diff --check\nNot-tested: Live EC2 deployment and production rollback
Constraint: The deployment hardening PR must include the verified G008 compliance head without rewriting either history.\nRejected: Rebase or cherry-pick | both would obscure the reviewed branch boundary or duplicate the compliance decision.\nConfidence: high\nScope-risk: moderate\nDirective: Preserve fbe1de0 as an ancestor of the deploy candidate.\nTested: Merge conflict check only; full Shopify verification follows on the combined head\nNot-tested: Live Shopify webhook delivery and EC2 deployment
Constraint: Device, server, sync, and alert evidence must remain independently visible without inferred green states. Rejected: Clamp negative progress gaps to zero | It hides server-ahead mismatches as successful synchronization. Confidence: high Scope-risk: narrow Directive: Preserve signed progress direction and require explicit empty alert evidence before rendering success. Tested: 604 node tests; 48 focused operational tests; lint; typecheck; build; public URL guard Not-tested: Live production route telemetry rendering
Constraint: Artifact preparation can fail after rollback pinning but before live runtime mutation. Rejected: One recovery flag for both artifacts and runtime | it stops a healthy target during build-only failures. Confidence: high Scope-risk: moderate Directive: Arm live recovery only immediately before stop and defer signals across the pointer commit. Tested: deployment hardening/runtime tests 23/23; shellcheck; actionlint; git diff --check Not-tested: Live EC2 deployment and production signal delivery
Constraint: The final Shopify candidate must include the updated G008 head without rewriting reviewed history. Rejected: Cherry-pick | preserving branch ancestry keeps compliance and route-state review evidence intact. Confidence: high Scope-risk: moderate Directive: Preserve 25e3bc3 and its fbe1de0 parent as ancestors of the deploy candidate. Tested: Merge conflict check; full combined Shopify verification follows. Not-tested: Live Shopify operations and EC2 deployment.
Constraint: Operators need the same no-op, artifact-cleanup, and pointer-signal guarantees enforced by the remote script. Confidence: high Scope-risk: narrow Directive: Keep this runbook synchronized with deploy transaction and rollback tests. Tested: git diff --check; combined Shopify tests 602/602 before documentation-only commit. Not-tested: Live EC2 deployment.
Constraint: A healthy running image may outlive its missing exact-SHA tag, while previous points to an override that requires that tag. Rejected: Retaining only rollback-<run-id> | successful cleanup deletes the sole image reference needed by previous. Confidence: high Scope-risk: moderate Directive: Restore and verify the prior exact-SHA tag before committing new release pointers or deleting the temporary rollback pin. Tested: focused deployment tests 24/24; full serial Shopify tests 603/603; compliance hang test isolated 1/1; build; typecheck; lint; public URL; actionlint; shellcheck; YAML; diff-check. Not-tested: Live EC2 deployment and production rollback.
6 tasks
…cation Constraint: GNU mv requires -T while BSD mv requires -h to atomically replace a destination symlink without dereferencing it. Rejected: Global test serialization | CI failures were deterministic GNU/BSD option incompatibility, not shared test state. Confidence: high Scope-risk: narrow Directive: Keep pointer replacement a same-filesystem atomic symlink rename on both GNU and BSD hosts. Tested: default npm test twice (604/604 each); serial suite 604/604; focused deployment 25/25; GNU mv simulation 1/1; build; typecheck; lint; public URL; actionlint; shellcheck; YAML; diff-check. Not-tested: Live EC2 deployment.
Constraint: A GNU-behavior harness must run identically on Linux and macOS without invoking either host-specific mv option internally. Rejected: Removing the GNU regression | it is the direct guard for the CI failure. Confidence: high Scope-risk: narrow Directive: Simulated GNU -T acceptance must perform a real atomic replacement without falling through to BSD -h. Tested: GNU pointer regression 1/1; focused deployment tests 25/25; node syntax; diff-check. Not-tested: Live EC2 deployment.
Constraint: A failed GNU rename must never be retried with BSD semantics against an unexpected directory path. Rejected: Operational GNU-to-BSD fallback | it can convert a failed replacement into a successful move inside a directory. Confidence: high Scope-risk: moderate Directive: Select one supported no-dereference rename mode before live mutation, reject non-symlink pointers, and verify readlink before publication. Tested: focused deployment 27/27; default parallel full 606/606; target-directory and forced GNU failure 3/3; actionlint; shellcheck; YAML; node syntax; diff-check. Not-tested: Live EC2 deployment.
Constraint: DB and runtime rollback must never proceed behind a pointer that may reference the candidate release. Rejected: Exit immediately after a partial snapshot restore | that can leave current, previous, runtime, and DB describing different releases. Confidence: high Scope-risk: narrow Directive: Restore previous before current; if snapshot restoration is not provable, republish and verify the complete candidate pointer set before fail-stop. Tested: focused hostile pointer tests; node --test tests/*.test.mjs twice in parallel 609/609 each; serial 609/609; npm test 630/630; build; typecheck; lint; public URL guard; bash -n; shellcheck; actionlint; YAML parse; git diff --check Not-tested: production deployment intentionally not run
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.
Change control: EVNSolution/clever-change-control#265
Outcome
Verification
Rollout
Manual workflow dispatch for production and kfood after merge; exact prior image and database rollback evidence must be recorded.