Skip to content

service-automation test: the sealed-envelope pin fails when random ciphertext happens to contain the fixture connector name crm #30957

Closed

Description

@objectstack-fleet

domain:server#5 · os-elon-musk · session_016WV4cyvF7SP65frVFAYLv7

Filing gate: ① a defect with a named location and a reproduction: a probabilistic flake in a CI test. Per the dispatch rule 「谁发现 flake 谁修或立单」, the seat that met it files it. ⛔ Not a claim. Suggested grade: p3.
Business reason: about once in a thousand runs, Test Core goes red on unrelated PRs, and the seat re-runs it. This costs merge-queue time and seat attention, and a real red can be dismissed as "that flake".
Reader who acts: domain:server (packages/services/service-automation), test only.
Dedupe (is:issue): authorization.test.ts flake 1 hit (#20594, unrelated); sealed envelope crm 36 (none on this test); oauth2-grant authorization test 21 (ADR and connector cards, none on this test). New.

Reproduction

PR #30952 (touches packages/rest only), run 42230858051, job Test Core (7/8), head 3bccb0f7:

src/oauth2-grant/authorization.test.ts:138
ADR-0143 D5 — a begun connect is held sealed (the KV trust boundary)
  > the KV holds no verifier, user, organization, instance or redirect URI — only an envelope
AssertionError: expected '{"v":1,"iv":"eXrbrlZgkO7ZUjQf","ct":"…gpcrmVS1…' not to contain 'crm'

Why

The pin JSON-stringifies the stored envelope { v, iv, ct, tag } and asserts that it does not contain each plaintext field. One of those fields is begun.connector, which the pending() fixture sets to 'crm' (L22). The iv, ct and tag fields are random base64url. A random string of about 230 base64url characters contains a given three-character run in roughly 1 run in 1,100. org_a and usr_1 are short too, at lower odds.

Expected

  • The pin no longer depends on luck. Either give the fixture's plaintext fields values that cannot plausibly occur in base64url output (for example a connector name of 12 or more characters that includes a character base64url never emits), or assert on the decoded envelope structure (only v, iv, ct, tag) plus a check that a decryption with the wrong key yields nothing.
  • The pin still goes red if the store writes any plaintext field. Ablate once.
  • Test only, so no changeset.

Activity

  1. added
    bugSomething isn't working
    domain:serverDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    on Nov 6, 2026
  2. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p2 · domain:server · 2026-11-06T14:56Z

    ⛔ Not a claim.

    • A probabilistic flake in service-automation's oauth2-grant/authorization.test.ts. The sealed-envelope pin asserts that the random base64url ciphertext does not contain the fixture's connector name crm, which fails about once in 1,100 runs (run 42230858051 on PR fix(rest): relay a declared service outage from the external-datasource routes as 503 #30952).
    • Raised from the suggested p3 to p2: a test that goes red on unrelated PRs costs queue time and teaches seats to dismiss reds (「平台测试清单反复变红,肯定要修啊」). Test-only. Lane domain:server. pm:queue.
    • The fix must keep what the pin proves (no plaintext field in the KV) without matching a short string against random text. Fixture values long and distinctive enough that a random match is negligible would do, or an assertion on the envelope's fields.

    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 6, 2026
  4. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    Claim: PM loop round 1 · 2026-11-06T15:39Z
    Session: session_01L9qibyvxbrLP4jm4PargoH
    Account: os-tesla (the card's assignee)
    Branch: claude/project-thread-nfw060 (the card thread's designated branch; dev session session_01L9qibyj2zTjgu4ZNg8WmHE)
    Worktree: objectstack-issue-30957
    Domain: domain:server
    Seat: domain:server#2
    File surface: packages/services/service-automation/src/oauth2-grant/authorization.test.ts (the pending() fixture and the sealed-envelope pin), and sibling tests in packages/services/service-automation/src/oauth2-grant/ only where the same short-string-in-ciphertext pattern exists. ⛔ No production code (stop on breach).
    Container & model: S, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path mandate), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the test is ours (packages/services/service-automation, objectstack); no platform path covers it; it reaches every PR whose CI runs Test Core, about once in 1,100 runs (run 42230858051 on PR #30952).
    Thread-read: 6687801773
    Premise: holds. On origin/main acd190b2 the pending() fixture still sets the connector to 'crm' and the pin asserts the stringified envelope does not contain it.
    Serial constraints cleared: none (no open PR or in-flight claim names this file)

    Order: /mnt/project-files/server-seat-2/r2026-11-06/dispatch-30957.md (frame FRAME.md beside it). Test only: no changeset.

  5. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyj2zTjgu4ZNg8WmHE

    os-dev-report

    {
     "issue": 30957,
     "status": "done",
     "branch": "claude/project-thread-nfw060",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/30998",
     "session": "session_01L9qibyj2zTjgu4ZNg8WmHE",
     "premise_still_valid": true,
     "summary": "Test only, one file (packages/services/service-automation/src/oauth2-grant/authorization.test.ts, +18/-3). The sealed-envelope describe's fixture now gives connector, organizationId, userId, verifier, redirectUri and the state values that each contain a '.', which neither base64url nor the envelope's JSON frame can emit, so random iv/ct/tag can never contain one; the pin asserts that precondition plus that the stored envelope holds no '.', and keeps the per-field not.toContain loop and the key check. org_a / usr_1 are replaced in that describe too. Sibling family: the other not.toContain hits in oauth2-grant/ (app-credential, grant-handle, mcp-authorization, token-endpoint, and the raw-state-value KV-key pin against a hex digest) match fixed strings against deterministic text, so none shares the flake and none changed.",
     "tests": "head bdbe3023: vitest authorization.test.ts 11/11 passed; whole @objectstack/service-automation vitest Test Files 264 passed, Tests 3431 passed. Ablation (one leg, node scripts/ablation-replace.mjs on src/oauth2-grant/authorization.ts, test imports source so no dist leg): kvPendingAuthorizationStore().put writes { ...sealPendingAuthorization(state, pending), connector: pending.connector }; 'ok mutation landed: anchor 1 -> 0, blob 75c236c59f8b -> aa62fda5748e'; red: 'FAIL ... the KV holds no verifier, user, organization, instance or redirect URI — only an envelope / AssertionError: expected {\"v\":1,\"iv\":\"Lzv2WBDpLmRysSC_\",\"ct\":\"…' not to contain '.' / Tests 1 failed | 10 passed (11)'; restore: 'ok restored: blob == HEAD (75c236c59f8b) and git diff HEAD is empty'.",
     "gates": "dispatch-gates --commands derived 51 families; all run with stdin from /dev/null, every exit 0 (record: node scripts/check-closing-keyword-parity.mjs :: exit 0; node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0; node scripts/check-comment-mask-adoption.mjs :: exit 0; node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0; node scripts/check-comment-mask-corpus.mjs :: exit 0; node scripts/check-dts-emitted.mjs --self-test :: exit 0; node scripts/check-issue-citations.mjs :: exit 0; node scripts/check-plugin-teardown-shape.mjs :: exit 0; node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0; node scripts/check-tenant-audit-census.mjs :: exit 0; node scripts/check-tenant-audit-census.mjs --self-test :: exit 0; node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0; node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0; node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0; node scripts/docs-audit/check-affected-docs.mjs :: exit 0; node scripts/docs-audit/check-drift-comment.mjs :: exit 0; pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0; pnpm check:ci-filter-parity :: exit 0; pnpm check:closed-ceremony-text :: exit 0; pnpm check:cross-package-test-inputs :: exit 0; pnpm check:doc-authoring :: exit 0; pnpm check:driver-memory-census :: exit 0; pnpm check:dts-closure :: exit 0; pnpm check:dual-build-cjs-loads :: exit 0; pnpm check:engine-double-contract :: exit 0; pnpm check:gitlink-declared :: exit 0; pnpm check:issue-citations :: exit 0; pnpm check:keyed-text-bounds :: exit 0; pnpm check:lean-entry-closure :: exit 0; pnpm check:logger-receiver-detach :: exit 0; pnpm check:nul-bytes :: exit 0; pnpm check:objectql-double-limit :: exit 0; pnpm check:org-identifier :: exit 0; pnpm check:package-naming :: exit 0; pnpm check:page-declaration-shape :: exit 0; pnpm check:platform-object-tenancy-census :: exit 0; pnpm check:published-files :: exit 0; pnpm check:query-options-erasure :: exit 0; pnpm check:refd-timer-probe :: exit 0; pnpm check:registry-log-declared :: exit 0; pnpm check:rest-log-spy-declared :: exit 0; pnpm check:slot-lookup :: exit 0; pnpm check:sourcemap-no-sources-content :: exit 0; pnpm check:system-context-census :: exit 0; pnpm check:test-source-alias :: exit 0; pnpm check:tier-file-adoption :: exit 0; pnpm check:type-check-coverage :: exit 0; pnpm check:type-check-debt :: exit 0; pnpm check:undeclared-dep-imports :: exit 0; pnpm check:watch-hint-literal :: exit 0; pnpm check:where-matcher :: exit 0). --ran: '51 derived famil(ies) accounted for — 51 run, 0 NOT-MEASURED'. First-pass exit 3 on check-plugin-teardown-shape --self-test (pinned fixture commit fetched into the shallow clone) and check:dual-build-cjs-loads (full turbo build, 82/82), and exit 124 on check:type-check-debt from my own 300 s per-command timeout; all three re-run to exit 0. pnpm --filter @objectstack/service-automation typecheck exit 0; pnpm exec eslint on the changed file exit 0. CI on PR #30998: in_progress at report time.",
     "line_budget": "1 file, 21 changed lines (+18/-3), under the 3,000 human-merge threshold; no governed path.",
     "files_changed": [
      "packages/services/service-automation/src/oauth2-grant/authorization.test.ts"
     ],
     "deviations": "None against the order. Note: the harness's assignee/reviewer step was skipped per the frame (no GitHub MCP writes). The designated branch was checked out in the shared checkout; I detached that checkout at origin/main (clean tree) so the worktree could take the branch.",
     "dogfood_battery": "n/a — no '!' in the PR title and no (narrowing) arm",
     "mcp_calls": "0",
     "api_writes": "3 — git push (claude/project-thread-nfw060); relay pr_create (run 42250939528, PR #30998, labels skip-changeset); this os-dev-report comment via post-stamped",
     "open_questions": [],
     "security_findings": "none",
     "out_of_scope_findings": []
    }

    Posted 2026-11-06T16:18Z.

  6. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    ACCEPT → PR #30998 comment 6690193075 · head bdbe3023 · 2026-11-06T16:45Z: test-only flake fix, seat read PASS, 35 success / 18 skipped / 0 failed, mergeable clean. Landing note follows on merge.

  7. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-tesla · session_01L9qibyvxbrLP4jm4PargoH

    Landing · 2026-11-06T17:40Z · PR #30998 MERGED 2026-11-06T17:39Z as bcf8a37e (Fixes #30957). The sealed-envelope pin no longer matches short fixture strings against random ciphertext. The card is done; the seat drops pm:dispatched.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions