You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Queue: the two translation-bundle lint gates red only in the merge queue, so a PR that declares an untranslated label passes its own CI and ejects its stack (6 ejections on 2026-11-08) #31512
both (stacked behind #31448; green on its own re-build at 11:25)
Each group after a fix or an ejection went green. main push Lint & Type Check stayed green throughout, so push-side lint does not run these two steps for those diffs either.
Ask
Find why a PR whose diff declares a label (platform-objects objects, settings manifests, spec-declared labels) does not run these two steps on its own pull_request CI. Either the steps' if: / path filters miss those paths, or the lane is affected-only and these steps sit outside the affected set.
Pin: a diff that adds one untranslated declared label reds on PR CI. CONTROL: a diff that touches no declared label does not run them.
Not measured
The exact trigger condition of the two steps for pull_request events, in lint.yml (id: check-generated-translation-bundles ≈L6361, check-no-new-untranslated-declared-labels ≈L6378).
Claim: PM loop round 1 · 2026-11-08T12:17Z
Session: card thread (dev), named in the amendment once it opens · seat session_01QsR2jTo666XXx9e1Gm21C6
Account: zhuangjianguo
Branch: named in the amendment (the card thread's branch)
Worktree: objectstack-issue-31512
Domain: domain:devx
Seat: domain:devx#2
File surface: .github/workflows/lint.yml (the trigger condition of check-generated-translation-bundles and check-no-new-untranslated-declared-labels), scripts/pm/dispatch-gates.data.mjs (+ dispatch-gates.mjs only if the table cannot express it), scripts/pm/dispatch-gates.self-test.mjs; skip-changeset; ⛔ no new gate, no change to the gates' logic or baseline, no ui/.github/**
Container & model: M, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: this repo's CI wiring (lint.yml runs the two steps on merge_group but not on the PR that adds the label) | no platform path covers it today: dispatch-gates --commands does not derive the two families | every PR that declares a label without translating it, six ejections on 2026-11-08 per the card's table
Thread-read: none
Premise: holds: both steps exist on origin/main58f66b93 (lint.yml L6361, L6378, continue-on-error: true); the dev re-measures the skip condition before code
Serial constraints cleared: none on lint.yml. The lane's in-flight PRs are #31429 (ci.yml, scripts/ci/**) and #31468 (fleet-write.yml); no shared file
Scope: the card's "Ask" bullets and its pin + CONTROL. Tier H (.github/workflows/**): the maintainer merges by hand. PR says Fixes #31512. Brief: /mnt/project-files/issue-31512/brief.md. Summons: the maintainer's 「开一个 devx 车道」 (this project, 2026-11-08T11:03Z).
Release: #31512 · back to pm:queue + pm:retriage · premise false (the dev's step-1 reading, no code written, no branch pushed)
Resume-from: none
Premise reading (dev session_01QsR2jTUMifZ947S4yb7zwU, checked by the seat)
No skip condition exists. In .github/workflows/lint.yml on origin/main the job typecheck-consumers (≈L5995) gates only on !cancelled() and the schedule gate (≈L5998). pull_request has no paths filter (≈L23). Neither check-generated-translation-bundles (≈L6360) nor check-no-new-untranslated-declared-labels (≈L6377) has an if:.
No lint.yml change can let a PR run see a locale its base lacks. The remedy is base freshness at landing (merge main before queueing when a translation bundle has landed since the PR's last run). That lives in the pm-dispatch landing rules (.claude/**, domain:skills) or in a repository setting, both outside this card's domain:devx surface. Please re-route or close as premise-false and re-file at the landing owner. A narrow remainder, deriving check:i18n-coverage beside check:i18n in dispatch-gates, is low value and the seat does not recommend dispatching it alone.
Full reading with run and job ids: the dev's step-1 note, held by this seat.
It becomes a landing rule, not a CI change: when a translation bundle (a new locale) has landed on main since a PR's last green run, the seat merges main and re-runs before queueing a PR that declares labels.
Where to write it is the lane's call: the pm-dispatch landing references (.claude/skills/pm-dispatch/**), or a note on the locale PRs themselves, which announce the new locale to open label PRs.
The repository setting "require branches to be up to date" would also cover it. That is the maintainer's call, so it is raised here only as an option.
p2 while the locale rollout continues; it drops to p3 once the planned locales have landed. pm:retriage removed, the lane is domain:skills, and the card stays in pm:queue. The original Ask (PR-side wiring) is withdrawn; the dispatch-gatescheck:i18n-coverage gap noted in the reading may ride the same PR.
Reading time 2026-11-08T12:31Z. Tree: objectstack-ai/objectstack @ 4894cfe (origin/main).
{
"issue": 31512,
"status": "done",
"branch": "claude/project-thread-86l2bq",
"pr": null,
"session": "session_01QsR2jTUMifZ947S4yb7zwU",
"premise_still_valid": false,
"summary": "No skip condition exists. lint.yml job typecheck-consumers (L5995) has the job condition `!cancelled() && needs.schedule-gate.outputs.skip != 'true'` (L5998), pull_request has no paths filter (L23), and the two steps (L6360 check-generated-translation-bundles, L6377 check-no-new-untranslated-declared-labels) have no step condition and are outside the family selector; lane-verdict.mjs reads their outcome on every event. PR #31448 run 42470886353 (head 46cd04b8, pull_request, 10:18Z) ran both green (job 128701119610, steps 23-24, 10:29:32-10:30:38Z). Positive control: PR #31448 run 42465007516 (08:56Z), job 128682352642, lane verdict RED on both steps, so the card's pin already holds on main. The queue reds are base drift: a NEW-LOCALE PR landed after a label PR's last PR run. #31440 (pt-BR, deac7f46, 08:27Z) after #31435's run 42461308826 (08:03Z), queue red 42463926000 (08:40Z, platform-objects DRIFTED (2), grew 0 to 1); #31466 (ru, 2ae3e301, 10:46Z) after #31448's run 42470886353 (10:18Z), queue red 42474612084 (11:11Z, grew 0 to 6). Fix commits 605c353a and 951de4cf name the late locale. The card's other rows are entries stacked behind those two: 6 ejections, 2 root PRs. Nothing in lint.yml can make a pull_request run see a locale its base lacks; the lever is base freshness at landing, outside this claim's surface. Seat accepted the reading and released the card to retriage.",
"tests": "none: no code written. Evidence is the CI run, job and step reads cited in summary (GitHub Actions read API), plus `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack packages/platform-objects/src/identity/sys-api-key.object.ts` at 4894cfe1, which derives check:i18n and check:i18n-stale-fill (kind: edits a file in a package that owns an i18n-extract.config.ts) and not check:i18n-coverage.",
"gates": "n/a: no diff, nothing derived (dispatch-gates: this branch changes nothing against origin/main, merge base 4894cfe16).",
"line_budget": "0 lines changed",
"files_changed": [],
"deviations": "none",
"dogfood_battery": "n/a: no PR",
"mcp_calls": "12: GitHub MCP reads only (issue_read x2, pull_request_read x2, actions_list x5, get_job_logs x3); no write tool",
"api_writes": "1: this report comment via post-stamped",
"open_questions": [
{ "question": "Where should the real cause (a locale bundle landing under an in-flight label PR) be fixed?", "options": ["A: landing protocol in pm-dispatch: before arming, merge main when an i18n bundle landed after the PR's last PR run (Tier S, .claude/**)", "B: repository setting requiring branches up to date (maintainer)", "C: derive check:i18n-coverage beside check:i18n in dispatch-gates (low value for this class: a local run sits on the same stale base)"], "recommendation": "A, because it targets the measured cause with no new gate and no repo-wide cost; triage decides the carrier" }
],
"security_findings": "none",
"out_of_scope_findings": ["carrier: triage (re-triage of #31512 per seat comment 6721491029) · noted, not filed"]
}
Full reading: the project file issue-31512/step1-reading.md (seat-held).
Claim: PM loop round 9 · 2026-11-08T13:15Z
Session: session_01QsR2jT34CXs5fCn3BDirZw
Account: zhuangjianguo (the seat's linked user; the card's assignee)
Branch: claude/project-thread-7j7fys (the card thread's designated branch, a measured platform exception to claude/issue-<n>-<slug>; dev session session_01QsR2jRG212pSNYcqZAmR1Q)
Worktree: objectstack-issue-31512
Domain: domain:skills
Seat: domain:skills#2
File surface: .claude/skills/pm-dispatch/references/landing-operations.md; optionally scripts/pm/dispatch-gates.data.mjs + scripts/pm/dispatch-gates.self-test.mjs (the check:i18n-coverage derivation, one table row, as triage allowed). Stop on breach; explain in the report.
Container & model: S, mode:thread, model: TIER_DEFAULT (.claude/** Tier S; contract review routed to the director seat), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: the landing protocol (pm-dispatch landing references) | no landing rule today names a locale bundle landing under an in-flight label PR | every label-declaring PR in the queue while the locale rollout continues: 6 ejections, 2 root PRs on 2026-11-08 (readings 6721491029 and the dev report on this card)
Thread-read: 6721525572
Premise: holds as retriaged. The original Ask (PR-side lint.yml wiring) is withdrawn; both steps already run on PR CI. The measured cause is base freshness: #31440 (pt-BR) and #31466 (ru) landed after the label PRs' last green PR runs. landing-operations.md is 102/102 lines, so the new rule is paid by deletion or folded into the sibling line L29 「基上缺已合修复 ⇒ merge main」.
Serial constraints cleared: none on landing-operations.md. Open PR #31454 also edits scripts/pm/dispatch-gates.self-test.mjs: the optional row rides only if it merges cleanly; whichever lands second merges main.
Dispatch order: pasted verbatim into the card thread's opening message (common rules + order, from the seat folder skills-seat-2/ of the project files). Writes: PR only via relay pr_create; comments, labels and bodies only via scripts/pm write tools; no GitHub MCP writes.
Landed · 2026-11-08T13:59Z — PR #31536 merged through the merge queue (merge commit dabef0f). It landed on the director's CONTRACT_REVIEW_TIER PASS 6722227989 for head b65ebb6.
landing-operations.md now carries the base-freshness rule: a label PR whose last green PR run predates a new locale bundle on main merges main and re-runs before auto-merge or enqueue, as the one exception to behind PRs enqueueing as they are. A translation-gate red from a late locale counts as the 「基上缺已合修复」 branch.
The optional check:i18n-coverage derivation was skipped. It is more than one row, and triage graded it low value. The repository setting "require branches to be up to date" stays the maintainer's call.
Activity
objectstack-fleet commentedon Nov 8, 2026
domain:devx#2 · zhuangjianguo · session_01QsR2jTo666XXx9e1Gm21C6
Claim: PM loop round 1 · 2026-11-08T12:17Z
Session: card thread (dev), named in the amendment once it opens · seat
session_01QsR2jTo666XXx9e1Gm21C6Account:
zhuangjianguoBranch: named in the amendment (the card thread's branch)
Worktree:
objectstack-issue-31512Domain:
domain:devxSeat:
domain:devx#2File surface:
.github/workflows/lint.yml(the trigger condition ofcheck-generated-translation-bundlesandcheck-no-new-untranslated-declared-labels),scripts/pm/dispatch-gates.data.mjs(+dispatch-gates.mjsonly if the table cannot express it),scripts/pm/dispatch-gates.self-test.mjs;skip-changeset; ⛔ no new gate, no change to the gates' logic or baseline, noui/.github/**Container & model: M,
mode:thread,model: default tier(dispatch-gates --tier: no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility: this repo's CI wiring (
lint.ymlruns the two steps onmerge_groupbut not on the PR that adds the label) | no platform path covers it today:dispatch-gates --commandsdoes not derive the two families | every PR that declares a label without translating it, six ejections on 2026-11-08 per the card's tableThread-read: none
Premise: holds: both steps exist on
origin/main58f66b93(lint.ymlL6361, L6378,continue-on-error: true); the dev re-measures the skip condition before codeSerial constraints cleared: none on
lint.yml. The lane's in-flight PRs are #31429 (ci.yml,scripts/ci/**) and #31468 (fleet-write.yml); no shared fileScope: the card's "Ask" bullets and its pin + CONTROL. Tier H (
.github/workflows/**): the maintainer merges by hand. PR saysFixes #31512. Brief:/mnt/project-files/issue-31512/brief.md. Summons: the maintainer's 「开一个 devx 车道」 (this project, 2026-11-08T11:03Z).objectstack-fleet commentedon Nov 8, 2026
domain:devx#2 · zhuangjianguo · session_01QsR2jTo666XXx9e1Gm21C6
Claim: PM loop round 1 · amendment · 2026-11-08T12:23Z
Amends: 6721389718 (Session and Branch only; every other line stands)
Session:
session_01QsR2jTUMifZ947S4yb7zwU(card thread, dev) · seatsession_01QsR2jTo666XXx9e1Gm21C6Branch:
claude/project-thread-86l2bqobjectstack-fleet commentedon Nov 8, 2026
domain:devx#2 · zhuangjianguo · session_01QsR2jTo666XXx9e1Gm21C6
Release: #31512 · back to
pm:queue+pm:retriage· premise false (the dev's step-1 reading, no code written, no branch pushed)Resume-from: none
Premise reading (dev
session_01QsR2jTUMifZ947S4yb7zwU, checked by the seat).github/workflows/lint.ymlonorigin/mainthe jobtypecheck-consumers(≈L5995) gates only on!cancelled()and the schedule gate (≈L5998).pull_requesthas no paths filter (≈L23). Neithercheck-generated-translation-bundles(≈L6360) norcheck-no-new-untranslated-declared-labels(≈L6377) has anif:.pull_request, 2026-11-08T10:18Z) has both stepssuccess; the seat re-read it. An earlier PR run of the same PR, 42465007516, has both steps red. So the card's pin ("adds one untranslated declared label → reds on PR CI") already holds onmain.605c353aand951de4cfsay the same. The other four table rows are PRs stacked behind those two.dispatch-gates --commandsalready derivescheck:i18nfor aplatform-objectsobject edit. It does not derivecheck:i18n-coverage, but that gap did not cause these reds: feat(plugin-auth,platform-objects): per-provider SSO sign-in options; invite_only refuses an uninvited SSO sign-in unless the provider allows JIT #31448's dev ran both on the same stale base and got exit 0.Ask to triage
No
lint.ymlchange can let a PR run see a locale its base lacks. The remedy is base freshness at landing (mergemainbefore queueing when a translation bundle has landed since the PR's last run). That lives in the pm-dispatch landing rules (.claude/**,domain:skills) or in a repository setting, both outside this card'sdomain:devxsurface. Please re-route or close as premise-false and re-file at the landing owner. A narrow remainder, derivingcheck:i18n-coveragebesidecheck:i18nindispatch-gates, is low value and the seat does not recommend dispatching it alone.Full reading with run and job ids: the dev's step-1 note, held by this seat.
objectstack-fleet commentedon Nov 8, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: retriage answer · premise corrected ·
domain:devx→domain:skills· 2026-11-08T12:31Z⛔ Not a claim.
domain:devx#2's reading (6721491029) is right. Both steps already run on PR CI: there is no skip condition inlint.yml, and PR feat(plugin-auth,platform-objects): per-provider SSO sign-in options; invite_only refuses an uninvited SSO sign-in unless the provider allows JIT #31448's own run 42470886353 ran both green. Triage filed without reading the PR runs.mainsince a PR's last green run, the seat mergesmainand re-runs before queueing a PR that declares labels..claude/skills/pm-dispatch/**), or a note on the locale PRs themselves, which announce the new locale to open label PRs.pm:retriageremoved, the lane isdomain:skills, and the card stays inpm:queue. The original Ask (PR-side wiring) is withdrawn; thedispatch-gatescheck:i18n-coveragegap noted in the reading may ride the same PR.Generated by Claude Code
objectstack-fleet commentedon Nov 8, 2026
domain:devx#2 · zhuangjianguo · session_01QsR2jTUMifZ947S4yb7zwU
os-dev-report
Reading time 2026-11-08T12:31Z. Tree: objectstack-ai/objectstack @ 4894cfe (origin/main).
{ "issue": 31512, "status": "done", "branch": "claude/project-thread-86l2bq", "pr": null, "session": "session_01QsR2jTUMifZ947S4yb7zwU", "premise_still_valid": false, "summary": "No skip condition exists. lint.yml job typecheck-consumers (L5995) has the job condition `!cancelled() && needs.schedule-gate.outputs.skip != 'true'` (L5998), pull_request has no paths filter (L23), and the two steps (L6360 check-generated-translation-bundles, L6377 check-no-new-untranslated-declared-labels) have no step condition and are outside the family selector; lane-verdict.mjs reads their outcome on every event. PR #31448 run 42470886353 (head 46cd04b8, pull_request, 10:18Z) ran both green (job 128701119610, steps 23-24, 10:29:32-10:30:38Z). Positive control: PR #31448 run 42465007516 (08:56Z), job 128682352642, lane verdict RED on both steps, so the card's pin already holds on main. The queue reds are base drift: a NEW-LOCALE PR landed after a label PR's last PR run. #31440 (pt-BR, deac7f46, 08:27Z) after #31435's run 42461308826 (08:03Z), queue red 42463926000 (08:40Z, platform-objects DRIFTED (2), grew 0 to 1); #31466 (ru, 2ae3e301, 10:46Z) after #31448's run 42470886353 (10:18Z), queue red 42474612084 (11:11Z, grew 0 to 6). Fix commits 605c353a and 951de4cf name the late locale. The card's other rows are entries stacked behind those two: 6 ejections, 2 root PRs. Nothing in lint.yml can make a pull_request run see a locale its base lacks; the lever is base freshness at landing, outside this claim's surface. Seat accepted the reading and released the card to retriage.", "tests": "none: no code written. Evidence is the CI run, job and step reads cited in summary (GitHub Actions read API), plus `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack packages/platform-objects/src/identity/sys-api-key.object.ts` at 4894cfe1, which derives check:i18n and check:i18n-stale-fill (kind: edits a file in a package that owns an i18n-extract.config.ts) and not check:i18n-coverage.", "gates": "n/a: no diff, nothing derived (dispatch-gates: this branch changes nothing against origin/main, merge base 4894cfe16).", "line_budget": "0 lines changed", "files_changed": [], "deviations": "none", "dogfood_battery": "n/a: no PR", "mcp_calls": "12: GitHub MCP reads only (issue_read x2, pull_request_read x2, actions_list x5, get_job_logs x3); no write tool", "api_writes": "1: this report comment via post-stamped", "open_questions": [ { "question": "Where should the real cause (a locale bundle landing under an in-flight label PR) be fixed?", "options": ["A: landing protocol in pm-dispatch: before arming, merge main when an i18n bundle landed after the PR's last PR run (Tier S, .claude/**)", "B: repository setting requiring branches up to date (maintainer)", "C: derive check:i18n-coverage beside check:i18n in dispatch-gates (low value for this class: a local run sits on the same stale base)"], "recommendation": "A, because it targets the measured cause with no new gate and no repo-wide cost; triage decides the carrier" } ], "security_findings": "none", "out_of_scope_findings": ["carrier: triage (re-triage of #31512 per seat comment 6721491029) · noted, not filed"] }Full reading: the project file
issue-31512/step1-reading.md(seat-held).objectstack-fleet commentedon Nov 8, 2026
domain:skills#2 · zhuangjianguo · session_01QsR2jT34CXs5fCn3BDirZw
Claim: PM loop round 9 · 2026-11-08T13:15Z
Session:
session_01QsR2jT34CXs5fCn3BDirZwAccount:
zhuangjianguo(the seat's linked user; the card's assignee)Branch:
claude/project-thread-7j7fys(the card thread's designated branch, a measured platform exception toclaude/issue-<n>-<slug>; dev sessionsession_01QsR2jRG212pSNYcqZAmR1Q)Worktree:
objectstack-issue-31512Domain:
domain:skillsSeat:
domain:skills#2File surface:
.claude/skills/pm-dispatch/references/landing-operations.md; optionallyscripts/pm/dispatch-gates.data.mjs+scripts/pm/dispatch-gates.self-test.mjs(thecheck:i18n-coveragederivation, one table row, as triage allowed). Stop on breach; explain in the report.Container & model:
S,mode:thread,model: TIER_DEFAULT(.claude/**Tier S; contract review routed to the director seat),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility: the landing protocol (pm-dispatch landing references) | no landing rule today names a locale bundle landing under an in-flight label PR | every label-declaring PR in the queue while the locale rollout continues: 6 ejections, 2 root PRs on 2026-11-08 (readings 6721491029 and the dev report on this card)
Thread-read: 6721525572
Premise: holds as retriaged. The original Ask (PR-side
lint.ymlwiring) is withdrawn; both steps already run on PR CI. The measured cause is base freshness: #31440 (pt-BR) and #31466 (ru) landed after the label PRs' last green PR runs.landing-operations.mdis 102/102 lines, so the new rule is paid by deletion or folded into the sibling line L29 「基上缺已合修复 ⇒ merge main」.Serial constraints cleared: none on
landing-operations.md. Open PR #31454 also editsscripts/pm/dispatch-gates.self-test.mjs: the optional row rides only if it merges cleanly; whichever lands second merges main.Dispatch order: pasted verbatim into the card thread's opening message (common rules + order, from the seat folder
skills-seat-2/of the project files). Writes: PR only via relaypr_create; comments, labels and bodies only viascripts/pmwrite tools; no GitHub MCP writes.objectstack-fleet commentedon Nov 8, 2026
domain:skills#2 · zhuangjianguo · session_01QsR2jRG212pSNYcqZAmR1Q
os-dev-report
{ "issue": 31512, "status": "done", "branch": "claude/project-thread-7j7fys", "pr": "https://github.com/objectstack-ai/objectstack/pull/31536", "head": "b65ebb6f", "session": "session_01QsR2jRG212pSNYcqZAmR1Q", "premise_still_valid": true, "files_changed": [".claude/skills/pm-dispatch/references/landing-operations.md"], "line_budget": "landing-operations.md 102 -> 102 (ceiling 102, headroom 0); +2 new lines (L33-34), L29 extended in place (68 -> 116 bytes), -2 deleted lines restated elsewhere (dirty re-read; post-merge closed_by_pull_requests read); max touched line 118 bytes vs 120 cap; no re-wrap", "gates": "dispatch-gates --commands at b65ebb6f: 17 derived, 17 run, all exit 0; --ran: 17 accounted, 0 NOT-MEASURED. Prereq: locked turbo build formula+lint, VERDICT command-exit 0. Body gates: check-changeset-no-major exit 0, check-adr-0087-registration exit 0, check-closing-keyword-parity exit 0, check-partof-closing-keyword exit 0. CI check-runs: in_progress at report time", "deviations": "optional check:i18n-coverage row in dispatch-gates.data.mjs NOT done: not a one-row change (self-test pin i18nHit.length === 3 and the i18n docblock move; open PR #31454 edits the same self-test file); platform-readings.md L88 behind rule not edited (outside surface), the new line names itself the exception", "dogfood_battery": "n/a: no ! in title, no (narrowing) arm", "mcp_calls": "4: GitHub MCP reads only (issue_read x3, pull_request_read x1); no write tool", "api_writes": "2: relay pr_create (#31536, label skip-changeset) and this comment via post-stamped", "security_findings": "none", "out_of_scope_findings": [] }objectstack-fleet commentedon Nov 8, 2026
domain:skills#2 · zhuangjianguo · session_01QsR2jT34CXs5fCn3BDirZw
Landed · 2026-11-08T13:59Z — PR #31536 merged through the merge queue (merge commit dabef0f). It landed on the director's
CONTRACT_REVIEW_TIERPASS 6722227989 for head b65ebb6.landing-operations.mdnow carries the base-freshness rule: a label PR whose last green PR run predates a new locale bundle on main merges main and re-runs before auto-merge or enqueue, as the one exception tobehindPRs enqueueing as they are. A translation-gate red from a late locale counts as the 「基上缺已合修复」 branch.The optional
check:i18n-coveragederivation was skipped. It is more than one row, and triage graded it low value. The repository setting "require branches to be up to date" stays the maintainer's call.pm:dispatchedremoved. Nothing left on this card.