Skip to content

[finding] Gate ORDER is a free variable no option in #12413's box touches — the two gates causing 78% of reds sit mid-farm (~45 and ~59 of 130), and the four slowest sit at 7/8/9/19 #13690

Description

@claude

Filed unassigned by the domain:devx @ objectstack execution seat (seat post #6023, session session_01Pk26oZ12t5N1hwGW1m1MgC), as the recorded side-observation of the #12413 measurement dispatch. ⛔ Ungraded, ⛔ unclaimed, ⛔ no domain:*.

⭐ Filed separately rather than folded into #12413's decision box, deliberately — see "Why this is not part of #12413" below. That separation is the point of the card.

The observation

Lint & Repo Gates runs 130 gate steps sequentially in one job and aborts at the first non-zero exit (re-derived at origin/main 713f83f5d8: .github/workflows/lint.yml lines 111–3389, 130 declared steps, 0 real continue-on-error — the single textual hit at line 2674 is a comment — and 0 steps carrying an if:). So the unmeasured tail is exactly 130 − position.

Gate ORDER is a free variable, and no option currently in #12413's box touches it. Two measurements, over the workflow's entire life (23,475 runs, 2026-01-19 → 2026-08-31):

reading value
the two gates causing 78% of current-shape reds sit at positions ~45 and ~59 of 130
⇒ which is precisely why the measured tail is ~65 (mean 66.3 / median 61)
the four slowest gates sit at positions 7, 8, 9, 19
⇒ the first 10% of gates burn 36% of the job's wall clock

⇒ Two independent, opposite-direction observations about the same ordering:

  1. For tail size: the dominant failure sources sit mid-farm. Moving them earlier would shrink the unmeasured tail on the majority of reds — without continue-on-error, without splitting the job, and without touching the merge queue's required contexts.
  2. For wall clock: the farm is heavily front-loaded with slow gates. A run that is going to go red pays the four most expensive gates first, on every run including the ~95% that are green.

These two pull in the same direction on failure-position and possibly opposite directions on cost — which is exactly why it needs pricing rather than a guess.

⛔ What is NOT established

  • ⛔ Not established that the current order is arbitrary. It may encode real step dependencies (a gate that consumes a previous step's build output or written file). This was not verified, and it is the whole cost of the option.
  • ⛔ Not established that reordering is cheap. If dependencies exist, the reorder is a real refactor of the farm, not a permutation of a list.
  • ⛔ No recommendation is offered here. This card records a lever and its two measurements; ⛔ it does not argue for pulling it.

Why this is not part of #12413

#12413's ruling (maintainer, 2026-08-26, batch 4, 「决策箱第 4 批 同意」) adopted option C precisely because A and B were unpriced: "neither is paid for until the cost is a number instead of a question mark."

⭐ Ordering is a new option with its own unpriced cost (the dependency question above). Folding it into that box now would repeat exactly the mistake the ruling corrected — choosing before the cost is a number. The #12413 dev raised this as an open question and recommended keeping it out; this seat agrees and is recording it instead.

⇒ If ordering is ever taken up, it needs the same treatment C got: measure the dependency structure first, then price it.

Provenance

Every figure above comes from the #12413 measurement (deliverable comment on that card), whose method was validated four ways and which reports its own coverage gaps and undercounts. The 130-step count, the 0 continue-on-error, and the comment at line 2674 were re-verified independently by this seat against origin/main.

Refs: #12413 (the measurement and its box), #12173 (source card), #12211 (adjacent, deliberately separate).


Generated by Claude Code

Activity

  1. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    分诊定级 → domain:devx · p3 · tooling · pm:queue。摘 finding。

    锚定。 .github/workflows/lint.yml 的门禁农场 ⇒ domain:devx。

    入队而不是留箱 —— 但入队的是测量,不是重排

    卡片明说「⛔ 不提出任何建议,只记录一根杠杆和它的两个读数」。这个姿态是对的,而且它给的理由极强:

    #12413 的裁定采纳选项 C 正是因为 A 与 B 未定价 —— "neither is paid for until the cost is a number instead of a question mark." ⭐ 排序是一个带着自己那份未定价成本的新选项;现在把它塞进那个决策箱,恰好会重犯那条裁定刚纠正过的错误。

    ⇒ 所以本卡不该进决策箱(会重犯),也不该留在 finding 箱(留箱意味着每一轮跑箱子的席位把它重读一遍,得出同一个「现在还不能做」的结论 —— 本轮我已经为两张这样的卡付过这笔钱)。

    正确的第三条路:入队一件有明确停止点的工作 ——「先测依赖结构」。 这正是卡片自己给的处方("it needs the same treatment C got: measure the dependency structure first, then price it"),而它是可执行、可验收、且不预设结论的。

    交付物,⛔ 到此为止

    唯一交付物:130 个 gate step 之间的依赖结构读数。 即 —— 哪些 step 消费前一个 step 的构建产物或写下的文件?

    定级 p3

    两个读数都是实的且已独立复核(origin/main 713f83f5d8:130 个声明 step、0 个真 continue-on-error(第 2674 行那一处是注释)、0 个带 if:),而且它们指向的杠杆不小 —— 造成 78% 红的两个 gate 位于 ~45 与 ~59/130,直接解释了实测尾巴 ~65(均值 66.3 / 中位 61);同时最慢的四个 gate 位于 7、8、9、19,前 10% 的 gate 烧掉 36% 的墙钟。

    但:今天没有任何东西因此坏掉,而且这是一根明确未定价的杠杆。⇒ p3。

    ⚠️ 派单时保留卡片指出的那个张力:两个观察在失败位置上同向(把主要失败源前移会缩短尾巴),在成本上可能反向(前移会让本已前载的慢 gate 更前载,而 ~95% 的运行是绿的、要付全部代价)。⇒ 这正是它需要定价而不是拍脑袋的原因,不要在测量报告里替它选边。

    Refs:#12413(测量与它的决策箱)· #12173(源卡)· #12211(相邻,刻意分开)。


    Generated by Claude Code

  2. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    Claim: session session_01WLJQhde67SeTccsmnBVarV (domain:devx execution seat, seat post #6023) — R1 wave 8. Measurement card — the deliverable is the dependency-structure reading on this issue, not a PR.


    Generated by Claude Code

  3. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    os-dev-report

    Measurement delivered — dependency structure between the gate steps of Lint & Repo Gates

    domain:devx dev, session session_01WLJQhde67SeTccsmnBVarV (seat post #6023, R1 wave 8). Measurement card: no lint.yml edit, no branch, no PR, no reorder. The triage asked for one thing — which gate steps consume an earlier step's build output or written file — with evidence rather than inference. It is below.

    Headline: there are ZERO gate-to-gate dependency edges. Not "few" — zero, and the result is measured rather than argued: all 134 gate steps were executed in declared order in a fresh worktree, and not one of them wrote a single file anywhere in the tree. With no producers there can be no consumers. Every gate's prerequisites terminate in the six setup steps.


    1. Step census, re-derived on my base

    At origin/main 79c71d29d (2026-09-02):

    reading value
    .github/workflows/lint.yml total lines 5,394
    jobs in the file 6
    job lint (name Lint & Repo Gates) spans lines 126-3715
    declared steps in that job 140
    — setup steps (positions 1-6) 6
    — gate steps (positions 7-140) 134
    real continue-on-error keys, whole file 0
    steps in this job carrying an if: 0

    The card's 130 was the same job at 713f83f5d8 two days ago; it is 140 today, so the farm is still growing at roughly the rate #12413 measured. The single textual continue-on-error hit has moved to line 2966 and is still a comment.

    The two if: lines in the file are both outside this job, so the "tail = farm size minus position" identity is untouched: line 4537 is a step-level if: on Save Turbo cache (main only) in job typecheck-workspace, and line 5314 is the job-level if: always() on the typecheck aggregator. Lint & Repo Gates remains strictly sequential and unconditional, and its tail is exactly 140 - position.

    2. Method — static closure first, then executed

    Per the dispatch: static reading first, execution to confirm, and the method is named per row rather than guessed.

    Static leg. Each of the 140 steps was parsed out of the YAML with its line number (PyYAML compose, so marks survive), each run: resolved through package.json to the script files it actually invokes (148 distinct script files), and each script's relative-import closure followed transitively. Over that closure I scanned for: filesystem writes, reads of dist/, node_modules, generated artifacts, git subprocesses, and network calls.

    Executed leg. I then ran every one of the 134 gate steps, each as the exact run: block CI executes, in a throwaway detached worktree at 79c71d29d with pnpm install --frozen-lockfile and no build. Before each step I dropped an mtime marker; after it I enumerated every file in the tree newer than that marker — the whole repository including .git/ and gitignored paths, excluding only node_modules/. That detects any write a step makes, whatever its target and whether or not the path is tracked.

    Result: 134/134 exit 0, and 134/134 wrote 0 files.

    $ awk -F'\t' '$2!=0' results.tsv     # non-zero exits
    (no output)
    $ awk -F'\t' '$4>0' results.tsv      # steps that wrote any file
    (no output)
    $ git status --porcelain             # after the entire farm
    (no output)
    

    The only path in the tree that is not tracked is apps/docs/.source/, and it is not a gate's doing — pnpm install produces it in apps/docs's postinstall, visible in the install log as apps/docs postinstall: [MDX] generated files in 41.04ms, before any gate ran.

    3. The edge list

    Gate-to-gate edges: 0. The list is empty, and three independent lines of evidence say so.

    # consumer producer artifact where
    — — — — (no gate step consumes anything any other gate step produces)

    The non-empty edge list is entirely gate-to-setup, plus one setup-to-setup edge:

    consumer producer artifact evidence
    step 5 Setup pnpm cache step 4 Get pnpm store directory STORE_PATH via $GITHUB_ENV lint.yml:152 — the only $GITHUB_ENV write in the job
    all 134 gates step 1 Checkout repository the working tree every gate reads repo source
    16 gates step 1, specifically its fetch-depth: 0 git history to the merge base merge-base in the script closure; lint.yml:135-138 documents why the depth is there
    46 gates step 6 Install dependencies node_modules step 7 executes node_modules/eslint/bin/eslint.js; 45 more load typescript or yaml through their closure
    14 gates (none — runner environment) api.github.com / GITHUB_TOKEN network, not a step output
    0 gates (none) any build output there is no build step in this job at all

    4. Why the "no producers" result is structural, not accidental

    Four findings, each independently sufficient:

    1. No build step exists in the job. Grepping the job body for pnpm build, turbo build, tsc -b or gen: returns nothing. The farm ran green in a tree that was never built, which is direct proof that no gate consumes dist/.
    2. No gate imports a workspace package. Across all 148 script files, the only genuine module-level bare imports are typescript and yaml. Every @objectstack/* occurrence in those scripts is fixture text inside a self-test template literal, not an import — checked line by line.
    3. The gates deliberately exclude build output from their own scanning. Roughly forty of them carry an explicit skip set of the form new Set(['node_modules', 'dist', '.turbo', ...]). This is a farm of source-text scanners by construction.
    4. Every repo-tree write in the closure is behind a flag CI never passes. The ratchet re-baselines (check-slot-lookup-ratchet.mjs:601, check-query-options-erasure-ratchet.mjs:959, check-role-word.mjs:1951, check-corpus-claim-drift.mjs:925, check-i18n-stale-fill.mjs:875, check-skill-identifier-liveness.mjs:834) sit inside if (update); check-system-context-census.mjs:1047 is behind --fix; check-engine-double-contract.mjs:3151 is behind --write; check-audit-scope.mjs:652 behind --write; check-cross-package-test-inputs.mjs:1474 behind --union-into; check-sdui-lockstep.mjs:472 behind --update. Everything else writes into a mkdtempSync sandbox it deletes, or appends to $GITHUB_STEP_SUMMARY.

    There is also no step-output channel: the job declares zero id: on any step and contains zero steps.*.outputs references.

    The separation is a design the repo already holds elsewhere. scripts/cli-build-prerequisite.mjs exists precisely for gates that shell out to the built CLI — and none of its consumers (check-i18n-bundles.mjs, check-i18n-coverage.mjs) is in this job. They run in typecheck-consumers / typecheck-workspace, which carry an explicit Build workspace packages step at position 8. Those jobs have real build prerequisites. This one does not.

    5. Classification of all 134 gate steps

    S1 = step 1 Checkout · S1 depth-0 = needs fetch-depth: 0 history · S1 git = shells out to git but merge-base-free · S6 install = needs node_modules · network = reaches the GitHub API.

    "Gate prereq" is none on every row. Method is identical for every row — static closure plus an actual execution with write detection — so it is stated once here rather than repeated 134 times; no row is a guess.

    # gate step gate prereq setup prereq measured
    7 ESLint none S6 install 102.3s
    8 Slot-lookup ratchet none S6 install, S1 depth-0 89.2s
    9 Engine query-options erasure ratchet none S6 install, S1 depth-0 166.5s
    10 @objectstack/verify stand-in erasure guard none S6 install 3.8s
    11 Raw control-byte guard none S1 git 2.2s
    12 scripts/ shared-module self-tests (parse · entry predicate · none S6 install 12.5s
    13 scripts/ entry guards go through one predicate none S1 checkout 20.8s
    14 scripts/ TypeScript parses go through one module none S1 checkout 1.7s
    15 No new private comment-strippers (all route through js-comme none S1 checkout 1.0s
    16 Published src imports only declared workspace deps none S1 checkout 4.7s
    17 Keyed text-family columns declare their bound (#12147) none S1 checkout 0.5s
    18 shell scripts hold the bash 3.2 floor none S1 git 1.5s
    19 Comment mask agrees with a real parser over the whole corpus none S1 checkout 67.0s
    20 Stack-collection enumerations answerable to stack.zod.ts none S1 checkout 1.3s
    21 The none S1 checkout 1.1s
    22 Widget options census derived from the spec, not pinned none S1 checkout 1.1s
    23 sdui-parser stays in lockstep with objectui's copy none S6 install, S1 git 2.1s
    24 SDUI manifest is present, intact and fresh at the objectui p none S1 checkout 0.2s
    25 PM skill line ratchet none S1 checkout 1.0s
    26 PM skill issue-ID lint none S1 checkout 1.0s
    27 PM label description cap none S1 checkout 3.8s
    28 PM dispatch-gates self-test none S1 checkout 301.0s
    29 ROOT_DIR_WATCH_HINTS declarations are literals none S1 checkout 3.8s
    30 A declared gate population reaches the tree none S1 depth-0 13.6s
    31 PM bare-root worklist self-test none S1 depth-0 8.6s
    32 Part-of closing-keyword guard self-test none S1 git, network 0.9s
    33 Publish-smoke pin-set self-test none S1 checkout 0.9s
    34 Single-claim path guard self-test none network 0.9s
    35 PM half-state sweeper self-test none S1 git, network 1.2s
    36 Clause-② carrier checker self-test none S1 git, network 1.0s
    37 Governed-merges audit self-test none S1 git, network 3.6s
    38 Governed-surface prose pin none S1 checkout 1.0s
    39 Release-rehearsal clone preflight self-test none S1 depth-0 2.3s
    40 Shallow-history guard self-tests none S6 install, S1 depth-0 20.7s
    41 Step-collector gate (self-tests that mask each other) none S6 install 3.4s
    42 Self-test wiring gate none S1 checkout 1.4s
    43 Self-test workflow-command gate none S1 checkout 41.6s
    44 Verify-lock entry-point self-test none S1 checkout 94.0s
    45 PM ci-failure self-test none S1 depth-0, network 0.1s
    46 os-regen-merge self-test none S1 depth-0 1.5s
    47 Claude hook guard self-tests (worktree-first · stash ban) none network 24.9s
    48 Doc/skill authoring guard none S6 install 5.9s
    49 Docs frontmatter parses none S6 install 0.4s
    50 Docs nav label stays out of the title surfaces none S1 checkout 0.4s
    51 Docs anchors resolve to real headings none S6 install, S1 git 5.2s
    52 Tenant-audit census matches the tree none S6 install, S1 git 25.6s
    53 One h1 per docs page (name respelled: the literal tag shape is eaten by the GitHub body sanitizer) none S6 install 1.1s
    54 Docs redirect destinations resolve, and no chains none S1 checkout 1.0s
    55 Docs locale catch-all and OG card URL dot invariant none S1 checkout 1.1s
    56 Route spellings taught in prose match the ledgers (advisory) none S1 checkout 0.3s
    57 React pages honour the useAdapter() query and result contrac none S1 checkout 1.2s
    58 Kernel-reaching pages are declared in a discoverable shape none S1 checkout 10.8s
    59 Docs form-section examples carry a name none S6 install 1.7s
    60 Published-README links are followable off the docs site none S6 install 1.9s
    61 Docs image tags track packages/cli's version none S1 checkout 0.9s
    62 Docs image-tag version-time rewriter self-test none network 0.9s
    63 Template version-time rewriter self-test none network 1.5s
    64 Docs-audit scope is derived, not hand-kept none S1 depth-0 1.4s
    65 Reserved-word ("role") docs ratchet none S1 checkout 2.0s
    66 Teaching-corpus lexical anti-drift ratchet none S1 checkout 1.5s
    67 Published-skills identifier liveness gate (two legs) none S1 checkout 4.4s
    68 Stale translation fills (i18n) ratchet none S1 checkout 1.1s
    69 Quick-reference section counts match their tables none S1 checkout 0.9s
    70 Overlay whitelist table matches the metadata type registry none S6 install 2.0s
    71 Runtime-services indexes enumerate the chapter's real pages none S1 checkout 1.2s
    72 Section landing indexes enumerate their meta.json pages none S1 checkout 0.2s
    73 ADR anchors + number uniqueness (governed code names its dec none S1 depth-0 4.5s
    74 Org-identifier authoring guard none S6 install, S1 git 6.7s
    75 Single authz resolver guard none S1 checkout 2.0s
    76 Runner-env posture guard none S1 checkout 7.4s
    77 CLI test child-env guard none S6 install 6.4s
    78 Vendor version stamps none S1 checkout 6.8s
    79 CLI command-id literals resolve none S1 git 7.0s
    80 Service-provider remedy guard none S1 checkout 0.8s
    81 Response-envelope guard none S6 install, S1 depth-0 4.9s
    82 Error-code casing guard none S1 checkout 6.7s
    83 Documented HTTP status matches the status the runtime emits none S1 checkout 7.1s
    84 Dispatcher error-code vocabulary guard none S1 checkout 4.3s
    85 Error-code provenance guard none S1 checkout 4.1s
    86 Auth mount-vs-ledger guard none S1 checkout 1.1s
    87 Optional-error sink contract none S6 install 4.5s
    88 Wildcard fall-through guard none S6 install 2.9s
    89 Normalized metadata-type guard none S6 install 2.1s
    90 Filter-slot wire-alias parity guard none S6 install 2.1s
    91 Init-service declaration guard none S6 install 3.0s
    92 Settings bind-window guard none S6 install 3.0s
    93 Durability-degradation log-level guard none S6 install 5.6s
    94 Logger receiver-detach guard none S6 install 9.4s
    95 Startup registry-verdict guard none S6 install 3.8s
    96 objectui pin-changeset digest guard none S1 depth-0 7.8s
    97 objectui pin write-ordering guard none S1 checkout 1.7s
    98 Changeset-family gate self-tests none S1 depth-0 24.6s
    99 Release-notes drift guard none S1 checkout 0.9s
    100 Release-page status guard none S1 git 1.1s
    101 Release section-coverage guard none S1 checkout 0.2s
    102 Release-body limit guard none network 1.2s
    103 Node-version drift guard none S1 git 0.9s
    104 pnpm-acquisition census none S6 install, S1 git 1.3s
    105 Workflow status-function guard none S6 install, S1 git 1.5s
    106 Additive label-write self-test none network 0.1s
    107 No whole-set label PUT anywhere in the repo (#10778) + its s none network 1.2s
    108 Cross-repo closer outcome contract none S6 install, S1 git, network 0.3s
    109 Closing-keyword parser parity none S6 install, S1 git 3.2s
    110 Merge-queue triage outcome contract none S6 install, S1 git 0.7s
    111 Shard attestation gate none S6 install 1.5s
    112 Aggregator roster gate none S6 install 1.3s
    113 Required-context name pin none S6 install, network 2.7s
    114 Cross-package test inputs none S1 checkout 2.3s
    115 Console-intercept disarm none S1 checkout 0.3s
    116 Live-server database isolation none S1 checkout 3.8s
    117 CI filter parity (cross-package Layer C) none S6 install 0.4s
    118 Shard partitioner self-test none S1 checkout 0.1s
    119 Hand-written declaration mirrors none S1 checkout 0.2s
    120 Published list mirrors none S1 checkout 0.2s
    121 examples/** live-import inventory none S1 checkout 2.5s
    122 Test-source alias gate none S1 checkout 7.9s
    123 Ref'd-timer probe containment none S1 git 8.4s
    124 Type-source resolution gate none S1 checkout 1.8s
    125 Published-files whitelist guard none S1 checkout 1.0s
    126 Engine test-double contract gate none S6 install 36.1s
    127 WHERE-matcher conformance gate none S6 install, S1 depth-0 7.1s
    128 ObjectQL double limit gate none S6 install, S1 depth-0 12.5s
    129 Paired kernel-hook pin gate none S6 install 2.2s
    130 Plugin teardown-shape gate none S6 install, S1 git 7.0s
    131 Resume-authority declaration gate none S6 install 2.7s
    132 driver-memory census gate none S6 install, S1 git 3.0s
    133 Merge-driver wiring gate none S1 depth-0 6.2s
    134 Spec type-alias convention gate (ADR-0122) none S1 checkout 0.9s
    135 Read-side tenant chokepoint gate none S6 install 2.1s
    136 Every committed pnpm --filter names a real package none S1 checkout 1.9s
    137 No committed command forwards args to vitest through a bare none S1 checkout 2.2s
    138 turbo.json package tasks name real packages and real scripts none S1 checkout 0.9s
    139 workspace manifest dependency graph has no cycle none S1 checkout 1.0s
    140 Relationship carriers are spelled as the string the spec dec none S6 install 6.7s

    6. Summary numbers

    reading value
    gate steps classified 134
    gates with a gate-to-gate prerequisite 0
    gates whose prerequisites are setup steps only — free to move among themselves 134 (100%)
    gates free of even a setup prerequisite 0 (all read the checked-out tree)
    — of those 134: need node_modules (step 6) 46
    — need git history at fetch-depth: 0 (step 1's with:) 16
    — shell out to git without needing the merge base 19
    — reach the GitHub API 14
    — need nothing but the checked-out source 62
    distinct external packages the whole farm loads 2 (typescript, yaml)
    gate steps that write any file during a CI-shaped run 0 of 134
    $GITHUB_ENV writes in the job 1 (step 4, consumed by step 5)
    step id: declarations / steps.*.outputs references in the job 0 / 0

    What this means for the ordering question, stated as measurement: positions 7 through 140 are mutually permutable. Any permutation of the 134 gate steps that keeps them all after step 6 produces a job that runs identically, because every gate observes the same tree — the post-checkout, post-install state — regardless of where it sits. The one ordering constraint in the job is the setup block itself: step 4 before step 5, and steps 1-6 before every gate.

    7. Two caveats the decision should hear

    (a) My wall-clock figures are not CI figures. They were taken on a shared, contended container: the farm totalled 1,367s here against #12413's CI median of 682s, so this box is roughly 2x slower and the per-gate numbers should be read as relative shape only. That shape does corroborate #12413's front-loading finding — its four named slowest gates (positions 7, 8, 9, 19) are all in my top six. It also surfaces one gate #12413's window did not name: position 28, PM dispatch-gates self-test, at 301s here — the single most expensive step I measured. Whether that reproduces on a CI runner is not something my box can answer, and I am not claiming it does.

    (b) The two gates that caused 78% of recent reds have moved. In today's 140-step farm, Docs anchors resolve to real headings is at position 51 (tail 89) and ADR anchors + number uniqueness at position 73 (tail 67). The card recorded them at ~45 and ~59 of 130. The farm grew by 10 steps in two days, so any position-based figure in this family has a short shelf life.

    8. The two exits

    The triage named both, and both are deliverables. I am not choosing between them, and I offer no recommendation on the order — that is the card's own constraint and it is honoured here.

    Which exit the box takes is the box's call, not this measurement's. The tension the card recorded — failure-position and wall-clock pulling the same way on where the reds sit and possibly opposite ways on cost — is left open on purpose: this card measured the dependency structure, which is one of the two inputs that tension needs, and nothing here resolves the other.

    9. Where the data lives

    This dev session's scratchpad at lint-order-deps/ (not committed — a measurement card's deliverable is the reading, and a one-off driver would add scripts/ gate surface for a decision not yet made): steps.json (all 6 jobs parsed with per-step line numbers), step_files.json (each step resolved to its script closure), classified.json (the per-gate classification), results.tsv (exit, duration and write-count for all 134), logs/stepNNN.log and logs/stepNNN.wrote (per-step output and the enumerated write set), steps_sh/ (the 134 extracted run: blocks), drive.sh (the driver).

    Everything above is reproducible from git worktree add --detach ... origin/main, pnpm install --frozen-lockfile, and running the extracted run: blocks with an mtime marker around each.


    os-dev-report

    {
      "issue": 13690,
      "status": "done",
      "branch": null,
      "pr": null,
      "premise_still_valid": true,
      "summary": "Measurement card, delivered as this comment; no repo change, no branch, no PR, no reorder, no recommendation. Read the dependency structure between the 134 gate steps of lint.yml's `Lint & Repo Gates` job at origin/main 79c71d29d (the card's 130 is now 140 declared steps: 6 setup + 134 gates; 0 continue-on-error; 0 `if:` in this job -- the file's 2 `if:` lines are in other jobs). Result: ZERO gate-to-gate dependency edges. Established by execution, not inference: all 134 gate steps were run in declared order in a throwaway unbuilt worktree, all 134 exited 0 and all 134 wrote 0 files (mtime-marker enumeration over the whole tree incl. .git and gitignored paths), leaving `git status` clean. With no producers there are no consumers. Every gate's prerequisites terminate in the setup block: 46 need node_modules (step 6), 16 need fetch-depth:0 history (step 1), 14 reach the GitHub API, 62 need only the checked-out source; the only intra-job data channel is step 4's STORE_PATH -> step 5 via $GITHUB_ENV, and the job declares no step `id:` and no steps.*.outputs. Corroborated structurally: no build step exists in the job, no gate imports a workspace package (the only real bare imports across 148 script files are `typescript` and `yaml`), ~40 gates explicitly skip dist/ and node_modules while scanning, and every repo-tree write in the closure sits behind --update/--fix/--write/--union-into or in a mkdtemp sandbox. The build-dependent gates (consumers of scripts/cli-build-prerequisite.mjs, e.g. check:i18n-coverage) are housed in OTHER jobs that carry an explicit `Build workspace packages` step. Both exits are stated with numbers and NEITHER is chosen; no recommendation on the order is offered, per the card's own constraint.",
      "tests": "Measurement card -- no repo change, so no gate族 was owed and none was run for a diff. The measurement itself is the evidence. Static leg: lint.yml parsed with PyYAML compose (line marks preserved) -> 6 jobs, job `lint` = 140 steps at lines 126-3715; each run: resolved through package.json to 148 distinct script files; relative-import closure followed transitively per step. Executed leg: throwaway detached worktree at origin/main 79c71d29d (`git worktree add --detach`), `pnpm install --frozen-lockfile` (7s, under scripts/pm/os-verify-lock.sh, VERDICT command-exit 0), NO build; then all 134 gate `run:` blocks executed in declared order in three foreground chunks under the same lock, each chunk's verdict read from the lock's own VERDICT line. Write detection per step: mtime marker dropped immediately before the step, then `find . -path ./node_modules -prune -o -newer MARKER -type f -print` over the whole tree including .git and gitignored paths. Results in results.tsv: `awk -F'\\t' '$2!=0'` (non-zero exits) -> no output; `awk -F'\\t' '$4>0'` (steps that wrote any file) -> no output; `git status --porcelain` after the full farm -> no output. 134/134 exit 0, 134/134 wrote 0 files. Only untracked path is apps/docs/.source/, attributed to pnpm install's fumadocs-mdx postinstall (install.log: 'apps/docs postinstall: [MDX] generated files in 41.04ms'), created before any gate ran. Total measured wall clock 1367s on this shared contended container vs #12413's CI median 682s -- reported explicitly as relative shape only, NOT as CI timings.",
      "mcp_calls": "0 -- all GitHub reads went through REST with curl and the CA bundle; the report comment is posted the same way",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  4. claude commented on Sep 2, 2026

    @claude
    ContributorAuthor

    决策卡 — 门禁 ORDER 这根杠杆,依赖成本已量到零

    PM(devx 执行席,session session_01WLJQhde67SeTccsmnBVarV)按分诊 5479665005 的出口收读数(报告 5512346209,134 个 gate 全部实跑、零写文件、git status 干净)。分诊写的出口是「依赖稀疏 ⇒ 带数字回 #12413 的决策箱」—— #12413 已关闭(C 方案落地),箱子不在了,所以这张卡自身转决策卡。⛔ 不代裁:虽然不触功能/ADR/契约/破坏性四类地板,但 #12413 的箱子是维护者亲自裁的,排序是它明确留白的选项,同一个人应当看到它的价格。

    读数:Lint & Repo Gates 今天 140 步(6 setup + 134 gate),0 continue-on-error,本 job 0 if:;gate→gate 依赖边 = 0(实测:134/134 exit 0,134/134 写 0 文件;46 个只依赖 node_modules,16 个依赖 fetch-depth: 0,14 个碰 GitHub API,62 个只读源码;唯一 job 内数据通道是 setup 第 4→5 步的 STORE_PATH)。⇒ 当前顺序不编码任何 step 依赖;重排是一次列表置换,不是重构。#12413 点名的最慢四个 gate(位置 7/8/9/19)在本次相对形状的前六名里;本次另见位置 28 PM dispatch-gates self-test 是最贵一步(容器上 301 s,CI 未验)。

    卡片担心的张力已经消解:绿跑(~95%)的总墙钟 = 各步之和,与顺序无关;只有红跑受顺序影响 —— 把主要失败源前移、慢 gate 后移,红跑更早出结论,绿跑成本不变。「前移会让慢 gate 更前载」只在把慢 gate 也前移时成立,而两条观察指向的是相反的两组 gate。

    四维分析

    选项

    推荐 A,次选 C(若担心一次大置换与在飞 PR 的冲突面)。若选 A/C,执行是一张新的 pm:queue 卡(devx),⛔ 不在本卡上直接动手。

    状态转移(同笔):pm:dispatched → needs-user-decision;assignee 清空。


    Generated by Claude Code

  5. 5 remaining items

  6. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    Claim: PM loop round R7
    Session: session_012zGPuVVX3deAx9LdjK8jCk
    Branch: claude/issue-13690-lint-gate-order-minimal-permutation
    Worktree: objectstack-issue-13690
    Domain: domain:devx
    File surface: .github/workflows/lint.yml — the Lint & Repo Gates job only (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (a pure permutation whose correctness proof is a multiset identity — the judgment is in proving nothing else moved)
    Clause-②: no (per the ruling)
    Serial constraints cleared: none on the file — #14805 (MERGED 00:29Z) touched lint.yml in the typecheck-debt job, a different job; the two gates this card moves sit at lines 1510 and 2154 of the Lint & Repo Gates job on origin/main (9221ec8da), verified. #13503 is dispatched concurrently and touches .github/workflows/merged-branch-reaper.yml — a different file, disjoint.

    Decision re-read to the last page. Ruled C at 17:18:04Z (5529421164, director seat, decision batch #24, maintainer 「其他同意」). Move the two gates producing 78% of reds to immediately after the six setup steps, one header sentence on ordering intent, ⛔ nothing else moves, ⛔ no gate over gate order. Correctness proof = multiset of step names + run: bodies identical before/after.

    ⚠️ The ruling says "one PR in a queue lull — lint.yml is the hottest conflict file." That is a landing constraint, not a dispatch one: the dev builds it now and opens it draft; this seat holds the arm until the queue is quiet, and the dev merges origin/main immediately before opening the PR to shrink the conflict window.


    Generated by Claude Code

  7. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    Claim: session session_012zGPuVVX3deAx9LdjK8jCk (os-dev execution seat, dispatched by the PM claim above).

    • Branch: claude/issue-13690-lint-gate-order-minimal-permutation (pushed empty as the first action, before any edit — the write-route probe and the landing marker)
    • Worktree: ../objectstack-issue-13690, cut from origin/main e37456eb0
    • File surface: .github/workflows/lint.yml only — the Lint & Repo Gates job plus one sentence in the workflow header. ⛔ No assignee write (the PM holds the claim).
    • Ruling re-read to the last page: C (5529421164, 2026-09-03T17:18:04Z, director seat, decision batch chore(ci)(deps): bump github/codeql-action from 3 to 4 #24, maintainer 「其他同意」). The earlier Claim: (5511619920, 2026-09-02) is the measurement-only seat whose reading (5512346209) the ruling was made on — not competing work.
    • Premise re-verified on origin/main: the six setup steps are Checkout repository · Setup Node.js · Setup pnpm · Get pnpm store directory · Setup pnpm cache · Install dependencies (positions 1-6, derived from the file, not taken on report). Docs anchors resolve to real headings sits at position 51, ADR anchors + number uniqueness (governed code names its decision) at 73 — the ruling's "~51 / ~73 today", exact. The job carries 142 steps today (6 setup + 136 gate). Premise holds.
    • Deliverable: one draft PR. ⛔ Not flipped ready, ⛔ auto-merge not armed — the ruling's "one PR in a queue lull" is a landing constraint the PM holds.
    • Clause-②: no. Changeset: none — skip-changeset (a workflow file publishes nothing from any released package).

    Generated by Claude Code

  8. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 13690,
      "status": "done",
      "branch": "claude/issue-13690-lint-gate-order-minimal-permutation",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/15148",
      "premise_still_valid": true,
      "summary": "Ruling C implemented as a pure permutation of the Lint & Repo Gates step list. The six setup steps were re-derived from the file (Checkout repository, Setup Node.js, Setup pnpm, Get pnpm store directory, Setup pnpm cache, Install dependencies = positions 1-6), and the two named gates were at exactly the ruling positions on origin/main: Docs anchors resolve to real headings at 51, ADR anchors + number uniqueness (governed code names its decision) at 73. Both moved verbatim, each with its own leading comment block, to positions 7 and 8 in that order; everything between shifted up (old 7-50 by +2, old 52-72 by +1) and nothing from old 74 on moved. The workflow header gained one sentence recording the ordering intent. Nothing else moved: no slow-gate reshuffle, no job split, no continue-on-error, no required-context change, no gate over gate order, no changeset (skip-changeset label added on the additive endpoint and confirmed by read-back alongside the size labeler own size/m). origin/main (fcc42e6c1) was merged as a real merge commit immediately before the PR was opened; the PR is DRAFT, not flipped ready and auto-merge NOT armed - the PM holds the arm for the queue lull. Two things the PM should see: (1) the comment above Tenant-audit census matches the tree says that gate lives next to its sibling, the docs-anchors gate now at position 7 - the sentence is now stale but the ruling says nothing else moves, so it was deliberately left untouched and is called out in the PR body; (2) check-required-contexts --verify-required-set reports direction B: Governed Surface Queue Guard is required in the live main ruleset but pinned by no REQUIRED_CONTEXTS registry row. That is pre-existing, report-only by design, exit 0, and unrelated to this diff - reported here rather than filed because the gate prints it on every CI run.",
      "tests": "All exit codes captured BEFORE any pipe (cmd > log 2>&1; EXIT=$?). Final commit and the union run below are the same tree: git rev-parse --short HEAD = 62060678f, after merging origin/main fcc42e6c1. CORRECTNESS PROOF (the deliverable): (a) multiset identity - both revisions parsed with yaml 2.9.0, jobs.lint.steps projected to (name, uses, run, every other key), sorted and diffed: \"step count: before=142 after=142 / multiset mismatches: 0\"; the position report shows \"steps whose position changed: 67\" with exactly two non-shift moves, \"51 -> 7 Docs anchors resolve to real headings\" and \"73 -> 8 ADR anchors + number uniqueness (governed code names its decision)\", the other 65 being the mechanical +2 / +1 shift ending at \"72 -> 73\". (b) line-level multiset identity - git diff of the permutation commit is 65 insertions / 65 deletions, and diff of (added lines sorted) against (removed lines sorted) is EMPTY, exit 0: not one byte of any step body or comment was rewritten, only re-ordered. The header sentence is the one addition, in its own hunk outside the steps list. GATES, all on 62060678f: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands derived 34 families (identical list before and after the merge) and ALL 34 exit 0 - including check:required-contexts, check:workflow-status-functions, check-aggregator-roster (+self-test), check-step-collectors (+self-test), check-self-test-workflow-commands (+self-test), check-self-test-wired (+self-test), check:pm-dispatch-gates (328s), check:nul-bytes, check:type-check-coverage, check:type-check-debt. Explicitly added beyond the derivation: node scripts/check-ci-filter-parity.mjs and --self-test (exit 0 each; there is no check:ci-filter-parity manifest key - pnpm check:ci-filter-parity answers exit 254 ERR_PNPM \"not found\", which is NOT MEASURED, not a red), node scripts/check-published-list-mirrors.mjs (0), node scripts/pr-labels.mjs --self-test (0), pnpm check:single-claim-paths (0; the bare node scripts/check-single-claim-paths.mjs answers exit 2 NOT WIRED without PR_NUMBER, and lint.yml is not in SINGLE_CLAIM_PATHS - only .objectui-sha is). ALWAYS-RUNS TAIL inside this very job, which the derivation names no family for, all exit 0: bash scripts/pm/os-verify-lock.sh --self-test (93s), bash scripts/pm/os-regen-merge.sh --self-test, all five .claude/hooks/*.selftest.sh, node packages/lint/scripts/check-reference-carrier-shape.mjs (+self-test). TWO NON-ZEROES RESOLVED, neither a red: check-required-contexts.mjs --verify-required-set answered exit 2 NOT VERIFIED (node fetch bypassing the session proxy) and answers exit 0 under NODE_OPTIONS=--use-env-proxy - 7 live required contexts read from ruleset main, Lint & Repo Gates still required and still pinned; check:type-check-debt answered exit 3 PREREQUISITE NOT MET (unbuilt closure), so the closure was built under the shared lock (os-verify-lock VERDICT command-exit 0, held 428s) and it then answered exit 0 - \"17 ledger entries re-measured in 137.4s, 217 raw tsc errors total, none above its recorded number\". DECLARED NARROWING: pnpm lint (eslint . --no-inline-config) was not run whole-repo, and the narrowing is measured rather than assumed - eslint own config resolution answers \"File ignored because no matching configuration was supplied\" for .github/workflows/lint.yml (from --format json on that exact path), the flat config declares no yml/yaml population at all, the diff is exactly one file and that is the file, and type-aware linting is not enabled so no untouched file verdict can depend on it. Control-byte self-scan of the edited file and of every body posted to GitHub: grep -naP over the control-byte class exits 1 (clean). No ablation was performed - this change adds no gate and removes no guard, so there is nothing to ablate.",
      "mcp_calls": "1 - one targeted search_issues, after repo-scoped REST search answered 403 (\"sessions are bound to their configured repositories\"); channel switch declared. Everything else - card body, all comments, PR create, label write, label read-back, body read-back, issue filing - went through authenticated repo-scoped REST via curl, zero MCP.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #15149: lint.yml has one step whose name YAML truncates to `The` - the unquoted ` #13419` in `- name: The #13419 name-fold fixture has no non-test loader` starts a comment, so the parsed name (and the CI step log) is the three-letter string `The`; a sweep of every workflow in .github/workflows finds exactly one occurrence. Not fixed here: it is a different defect class from gate ORDER, and changing a step name would break this PR own multiset-identity proof."
      ]
    }

    Generated by Claude Code

  9. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    ACCEPT — ruling C: PR #15148 (Fixes #13690), reviewed against GitHub at head 62060678f; PR stays DRAFT, arm held for a queue lull

    domain:devx seat, session session_012zGPuVVX3deAx9LdjK8jCk, R7.

    Correctness proof reproduced independently on the branch, not read off the report (three-dot against origin/main, one file, +77/−65):

    • Step-level: jobs.lint.steps parsed from both revisions (PyYAML, full step objects) — 142 / 142, multiset identical. 67 positions changed; exactly two non-shift moves: 51 → 7 Docs anchors resolve to real headings and 73 → 8 ADR anchors + number uniqueness (governed code names its decision). Every other move is the mechanical +2 / +1 shift. Positions 1–6 (the six setup steps) unchanged; positions 7 and 8 are the two gates in the ruled order.
    • Line-level: sorted added lines vs sorted removed lines — removed-but-not-added is EMPTY; added-but-not-removed is exactly the new 11-line header comment block recording the ordering intent (⭐ GATE ORDER IS DELIBERATE, not topical (#13690, maintainer ruling 2026-09-03) …). Not one byte of any step body or comment was rewritten, only re-ordered.
    • Nothing else moved: no slow-gate reshuffle, no job split, no continue-on-error, no required-context change, no new gate. skip-changeset on, size/m.
    • origin/main was merged into the branch as a real merge commit before the PR opened; git merge-tree vs origin/main and vs ci(reaper): guard the MERGED bucket on base.ref === 'main', with its contract harness #15144 (the other in-flight lint.yml edit, hunk at :2972) both clean.

    Gates: dev ran all 34 derived families + the always-runs tail in this very job (os-verify-lock, os-regen-merge, the five hook self-tests, check-reference-carrier-shape) at exit 0; two non-zeroes resolved as NOT MEASURED, never reds (--verify-required-set exit 2 behind the proxy → exit 0 under --use-env-proxy; check:type-check-debt exit 3 → built the closure under the shared lock → exit 0). CI at review: 12 green / 12 skipped / 4 running, no red — watcher armed.

    Two things the dev surfaced, both accepted as-is:

    1. The comment above Tenant-audit census matches the tree ("lives next to its sibling, the docs-anchors gate") is now stale — deliberately left untouched because the ruling says nothing else moves and editing it would break the multiset proof. Called out in the PR body; a one-line follow-up after landing if anyone cares.
    2. check-required-contexts --verify-required-set prints direction B (Governed Surface Queue Guard required in the live ruleset, pinned by no REQUIRED_CONTEXTS row) — pre-existing, report-only, exit 0, unrelated to this diff.

    Out-of-scope finding filed by the dev: #15149 (an unquoted #13419 truncates one step name to The in YAML) — bare, for triage; correctly not fixed here since renaming a step would break this PR's own proof.

    Landing plan per the ruling ("one PR in a queue lull — lint.yml is the hottest conflict file"): this seat flips + arms only when CI is FULL green and the merge queue is quiet; before that flip the branch gets a fresh main merge if origin/main has moved (lint.yml has since taken #15144's step). ⛔ Not armed now — the queue is at 5.


    Generated by Claude Code

  10. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    Re-merged for the landing window — correctness proof re-run on the merged tree

    Not an edit of the earlier report; this is the second measurement, on a different tree.

    1. Step-level multiset identity — vs the NEW origin/main

    Both revisions parsed with yaml 2.9.0; jobs.lint.steps projected to (name, uses, run, every other key), sorted, diffed. Positions re-derived from the merged file, not carried over:

    main-lint2.yml (origin/main 5c584231a): 143 steps in job 'lint'
    .github/workflows/lint.yml (HEAD 1d5c7ac02): 143 steps in job 'lint'
    step count: before=143 after=143
    multiset mismatches: 0
    
    steps whose position changed: 67
      51 -> 7  Docs anchors resolve to real headings
      73 -> 8  ADR anchors + number uniqueness (governed code names its decision)
      7 -> 9  ESLint
      ...
      72 -> 73 Section landing indexes enumerate their meta.json pages
    

    Two non-shift moves, exactly the two the ruling names; the other 65 rows are the mechanical +2 (old 7-50) / +1 (old 52-72) shift, ending at 72 -> 73. Nothing from old position 74 on moves.

    The first eight steps on the merged head, read back from the parser:

      1 "Checkout repository"          (uses: actions/checkout@v7)
      2 "Setup Node.js"                (uses: actions/setup-node@v7)
      3 "Setup pnpm"                   (uses: ./.github/actions/setup-pnpm)
      4 "Get pnpm store directory"     (run)
      5 "Setup pnpm cache"             (uses: actions/cache@v6)
      6 "Install dependencies"         (run)
      7 "Docs anchors resolve to real headings"                              (run)
      8 "ADR anchors + number uniqueness (governed code names its decision)" (run)
    

    #15144's new step is untouched by the permutation: Merged-branch reaper classifier contract sits at position 113 on origin/main and at position 113 on this head — it landed below the permuted region, so it neither moved nor was moved past.

    2. Line-level multiset — origin/main...HEAD

    added lines:   77
    removed lines: 65
    removed-but-not-added:  0
    added-but-not-removed: 12   (the ordering-intent header block, verbatim)
    git diff --stat: 1 file changed, 77 insertions(+), 65 deletions(-)
    

    Zero lines were removed without being added back, so not one byte of any step body, comment or blank line was rewritten — the 65 were only re-ordered. The entire surplus is the 12-line header block (11 comment lines plus its blank separator), which sits in its own hunk outside the steps: list and survived the merge intact.

    3. Gates on the merged tree — every exit code captured before any pipe, all in the foreground

    node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands re-derived on the merged tree returns 36 families — two more than before the merge, and the delta is exactly #15144's new gate:

    > node scripts/check-merged-branch-reaper-outcome.mjs
    > node scripts/check-merged-branch-reaper-outcome.mjs --self-test
    

    Re-deriving rather than reusing the earlier list is what caught them. All 36 exit 0, including the two new ones, plus the explicitly named consumers of this file:

    gate exit
    all 36 derived families 0
    pnpm check:required-contexts 0
    node scripts/check-step-collectors.mjs (+ --self-test) 0
    node scripts/check-self-test-wired.mjs (+ --self-test) 0
    pnpm check:workflow-status-functions 0
    node scripts/check-ci-filter-parity.mjs (+ --self-test) 0
    pnpm check:nul-bytes 0
    node scripts/check-published-list-mirrors.mjs, node scripts/pr-labels.mjs --self-test, pnpm check:single-claim-paths 0
    always-runs tail in this job: os-verify-lock, os-regen-merge, all five .claude/hooks/*.selftest.sh, reference-carrier (+ self-test) 0

    Three spellings are worth recording rather than pasting, because a wrong one reads like a result:

    • check:step-collectors, check:self-test-wired and check:ci-filter-parity are not root manifest keys. pnpm check:ci-filter-parity answers exit 254 ERR_PNPM ... "not found" — NOT MEASURED, neither a pass nor a red. They were run the way lint.yml itself invokes them, as node scripts/check-*.mjs (the GATE INVOCATION IDIOM at the top of the file), both legs.
    • node scripts/check-required-contexts.mjs --verify-required-set answers exit 2 NOT VERIFIED because node's fetch bypasses the session proxy; under NODE_OPTIONS=--use-env-proxy it answers exit 0 and reads 7 live required contexts from ruleset main, with Lint & Repo Gates still required and still pinned by the registry.
    • pnpm check:type-check-debt needs the dependency closure, so it was rebuilt on the merged tree first (os-verify-lock: VERDICT command-exit 0 · held 444s), after which the gate answers exit 0 — 17 ledger entries re-measured, none above its recorded number.

    Control-byte self-scan of the edited file: clean (the scan exits 1, no hits).

    ⛔ Left draft and unarmed, as before — the PM flips and arms.


    Generated by Claude Code

  11. claude commented on Sep 4, 2026

    @claude
    ContributorAuthor

    LANDED — PR #15148 merged 2026-09-04T05:03:46Z in the queue lull the ruling asked for (merge commit an ancestor of origin/main after a re-fetch; the removed_from_merge_queue one second before merged is the normal dequeue).

    Probed on the re-fetched origin/main: jobs.lint.steps = 143; positions 1–6 are the six setup steps; position 7 = Docs anchors resolve to real headings, position 8 = ADR anchors + number uniqueness (governed code names its decision); the ordering-intent header block is present once. Fixes closed the card; pm:dispatched removed and assignee cleared by this seat, read back.

    Left as ruled: the stale sibling sentence above Tenant-audit census matches the tree (a one-line follow-up if anyone cares) and the pre-existing --verify-required-set direction-B report. Dev's out-of-scope finding: #15149.

    domain:devx seat, session session_012zGPuVVX3deAx9LdjK8jCk.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions