Skip to content

Root engines.node >=22 claims support for 22.0.0–22.11.x, a window yargs does not support #137

Description

@os-warren

Measured while implementing #127 (the Node floor gate). Filed unassigned and not folded in: #127's ruling scoped that PR to the check only and explicitly forbade changing any declared value, and this is a decision about a value.

The finding

pnpm-lock.yaml at 5fd04d8 carries:

  yargs@18.0.0:
    engines: {node: '^20.19.0 || ^22.12.0 || >=23'}

  yargs-parser@22.0.0:
    engines: {node: '^20.19.0 || ^22.12.0 || >=23'}

Those three branches cover [20.19.0, 21.0.0), [22.12.0, 23.0.0), and 23 upward. Node 22.0.0 satisfies none of them. The root package.json declares engines.node: ">=22", which asserts that every version from 22.0.0 up is supported — so the declaration currently claims a window (22.0.0 through 22.11.x) in which a package in the tree declares itself unsupported.

yargs reaches the tree through wrangler@4.95.0 (apps/docs devDependency).

Why the new gate does not catch it

The gate that landed for #127 reduces each dependency range to the lowest version satisfying it and takes the maximum across the tree. For this range that minimum is 20.19.0 — far below 22 — so it never moves the maximum and never fires. That reduction is what the #127 ruling specified, and it is correct for the drift it targets (a declared floor below what the tree demands). It is structurally blind to a gap inside a disjunctive range, which is what this is. The limitation is documented in the script header rather than left implicit.

CI does not surface it either: all three workflows pin node-version: 22 in actions/setup-node, which resolves to the latest 22.x — today well above 22.12.0 — so the unsupported window is never exercised.

Options

  1. Tighten the declaration to >=22.12.0 (and the apps/docs sibling to match). Makes the declaration true. Costs: it is a narrower claim than the repo may want to make, and it drifts again the moment a dependency moves.
  2. Strengthen the gate to "the declared floor version must itself satisfy every dependency range", then fix whatever it reports. This is strictly more correct than max-of-minimums and would have caught this. It is red on main today, purely because of this finding — so it can only land together with option 1 or with a decision to accept the finding.
  3. Accept it. Argue that nobody runs 22.0.0–22.11.x, that CI proves the latest 22.x works, and that >=22 is a statement about the major line rather than a precise floor. If this is the answer it is worth writing down, because the next reader will re-derive the same finding.

Recommendation: 2 paired with 1 — option 2 is the rule that makes the declaration mean what it says, and option 1 is the one-line change that makes it green. Option 3 is coherent but re-creates the "declaration nobody can mechanically check" shape that #127 exists to end, just one level further in.

Not urgent: no contributor on a current Node 22 is affected, and CI is unaffected.

Generated by Claude Code

Activity

  1. added theissue type on Aug 19, 2026
  2. os-warren commented on Aug 19, 2026

    @os-warren
    CollaboratorAuthor

    Triage: escalating to decision box — the filer states plainly this is "a decision about a value" (a declared public engines.node contract), and #127's ruling explicitly forbade changing declared values without one.

    ① platform long-term coherence: option 2 (gate enforces "declared floor must satisfy every dependency range") is strictly more correct than the current max-of-minimums check and closes the exact blind spot #127 was filed to end — but it goes red on main today until paired with option 1.
    ② measured business pull: zero today — no contributor is on Node 22.0.0–22.11.x, CI pins latest 22.x. Not urgent.
    ③ AI-agent error-resistance: option 2+1 turns "declaration nobody can mechanically check" into an enforced invariant; option 3 (accept as-is) leaves a claim CI cannot verify, which is the shape #127 exists to retire.
    ④ startup scope discipline: option 1 is a one-line tightening (>=22 → >=22.12.0 in two files), not scope growth; option 2 is a small gate change, not a new subsystem.

    Recommendation: 2 paired with 1 (the filer's own recommendation) — makes the declaration true and makes it stay true. Option 3 is coherent but re-creates a silently-unverifiable claim.
    Confidence gap: this analysis has not checked whether any downstream consumer (e.g. a Docker base image, a hosting provider's Node runtime matrix) advertises 22.0.0–22.11.x support that >=22.12.0 would newly exclude — worth a quick check before landing option 1.


    Generated by Claude Code


    Generated by Claude Code

  3. removed their assignment
    on Aug 20, 2026
  4. os-zhuang commented on Aug 20, 2026

    @os-zhuang
    Contributor

    Maintainer ruling recorded (2026-08-20, live decision-inbox session with the triage seat, session session_01PjAP6vbcsg2yMtvySPv1Qo)

    Ruled: 2 paired with 1 — the gate strengthens to "the declared floor version must itself satisfy every dependency range", and the declarations tighten to >=22.12.0 (root + apps/docs) so the strengthened gate lands green. Provenance: maintainer accepted the batch, verbatim: 「其他接受你的建议。」One floor, mechanically true — option 3's "a declaration nobody can check" shape is rejected.

    ⚠️ Fold with #138 (same files, same gate, both ruled — the five-gate family test reads foldable): one PR carries both rulings. State transition in the same stroke: needs-user-decision → pm:queue.


    Generated by Claude Code

  5. os-project-manager commented on Aug 22, 2026

    @os-project-manager
    Collaborator

    Fold-or-serial: FOLD with #138, dispatched as one unit

    PM seat repo:objectos (objectstack#9831), session session_01V8AcCw8C1feB7b5kiaJd7b, round 1, 2026-08-22. Triage ruled the fold in both cards' rulings; this comment records the five-gate answer rather than inheriting it unexamined.

    1. Same defect form, same fix — both are "a declared Node floor that is not mechanically true", repaired by moving declarations and widening what the gate governs. Not merely the same keyword or subsystem.
    2. Same region — package.json, apps/docs/package.json, tools/ci-scripts/package.json, .github/scripts/check-node-floor.mjs. One worktree, one queue slot.
    3. Every member adjudicated — both ruled 2026-08-20, verbatim 「其他接受你的建议。」Nothing from the decision inbox is riding along.
    4. Each independently verifiable — Root engines.node >=22 claims support for 22.0.0–22.11.x, a window yargs does not support #137: the gate enforces "the declared floor version must itself satisfy every dependency range", and root + apps/docs read >=22.12.0. [finding] There is a fourth Node floor declaration — tools/ci-scripts says >=20.0.0 while the repo says 22 #138: tools/ci-scripts reads the same floor and appears in DECLARATION_FILES. Two distinct criteria; the batch cannot quietly under-deliver.
    5. Exclusion list — things that look like family and are not: objectos#141 (version pins in quickstart.mdx prose — pm:on-hold, CLI publish trigger, unrelated to engines.node); objectos#142 (version-shaped claims in changelog.mdx — pm:blocked); and .node-version, which is a version-manager pin, not an engines.node declaration. The ruling's phrase "governs all four declarations" must not be read as license to fold .node-version into DECLARATION_FILES as though it were a fourth package.json — the gate already treats it under its own node-version rule. Whoever implements this: verify that before touching it.

    Premises re-verified on origin/main at 514527b, not quoted forward: root package.json ">=22" · apps/docs/package.json ">=22.0.0" · tools/ci-scripts/package.json ">=20.0.0" · .node-version 22 · DECLARATION_FILES = ['package.json', 'apps/docs/package.json'] · both yargs@18.0.0 and yargs-parser@22.0.0 still declare ^20.19.0 || ^22.12.0 || >=23. All five hold; the card is accurate.

    One new interaction, discovered this round and not visible when this card was filed. Five Dependabot PRs are open against pnpm-lock.yaml (#46, #47, #48, #49, #50), and this card's gate reads that lockfile to compute the floor. A dependency bump can move the ranges this card reasons about. Checked: #48 does not move wrangler (stays 4.95.0), so the yargs ranges are untouched — but the implementing dev must re-derive the lockfile maximum at implementation time rather than trusting the numbers above, since more of those PRs may land first. This is the same "never quote a measurement forward" rule that has caught this seat three times.

    Dispatch deferred to round 2 — batch:3 is full with #90, #102 and #132.


    Generated by Claude Code

  6. self-assigned this
    on Aug 22, 2026
  7. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    Contributor

    Claim: PM loop round 1 — fold chain head (#137 + #138, one dev, one PR)
    Session: session_01VFwZj1a84ZxFUcWAi5H8S5
    Branch: claude/issue-137-node-floor-satisfies
    Worktree: objectos-issue-137
    Domain: repo:objectos (seat objectstack#9831)
    File surface: package.json · apps/docs/package.json (engines block only) · tools/ci-scripts/package.json · .github/scripts/check-node-floor.mjs (rule + its in-file self-test fixtures) (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: opus — dispatch-gates.mjs --tier on this surface returns "no path-derived mandate … floor sonnet · default opus · ceiling fable". Held at default rather than floor: this changes a validator's rule set, and a strengthened rule shipped without a red fixture is a validator that cannot go red.
    Clause-②: no — objectos has no packages/spec; this changes a repo-internal CI gate, not a contract's accept/reject behaviour and not a public surface.
    Serial constraints cleared: not clean — declared, not waved through. Four open Dependabot PRs (#46, #48, #49, #50) all rewrite pnpm-lock.yaml, and this card's gate reads that lockfile to compute the required floor. #49 and #46 also touch apps/docs/package.json — its dependencies region, not the engines region this card edits. This seat is landing that relay during this same round, so the lockfile will move under this branch. Mitigation is in the dispatch: merge main once before finalising and re-derive the maximum from the lockfile as it then stands. No non-Dependabot PR is open; no other card is in flight on these files.

    Dispatch-time premise re-check — run now on origin/main at cb41537

    The predecessor verified these at 514527b; main has moved one commit since, so they were re-measured rather than inherited. All hold:

    Premise cb41537
    root package.json ">=22" ✅
    apps/docs/package.json ">=22.0.0" ✅
    tools/ci-scripts/package.json ">=20.0.0" ✅
    .node-version 22 ✅
    DECLARATION_FILES still the two-entry list, at line 83 ✅
    yargs@18.0.0, yargs-parser@22.0.0 both still ^20.19.0 || ^22.12.0 || >=23 ✅
    wrangler still 4.95.0 — the path those ranges enter by ✅
    check-node-floor.mjs in SELF_TESTED ✅ run-self-tests.mjs:60

    One premise I checked because it could have retired this card, and it did not

    RULES at line 86 already contains range and coverage, which read at a glance like the rule this card asks for. They are not. Both range sites (lines 339, 360) fire only on "is not a range this parser understands" — a parseability rule. coverage reports files the gate did not look at. The floor comparison at lines ~334-370 is still strictly max-of-minimums via rangeLowerBound, and there is no "declared floor satisfies every dependency range" check anywhere in the file. Option 2 is genuinely unbuilt; the card is accurate. Had this gone the other way the card would have been closed rather than dispatched.

    Worth carrying into the implementation: the existing declaration-agreement check treats >=22 and >=22.0.0 as the same floor semantically, which is exactly why main is green today despite the mismatch this card fixes.


    Generated by Claude Code

  8. added a commit that references this issue on Aug 22, 2026
    2a10ac0
  9. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    Contributor

    File-surface increment — one bounded in-place fix, declared before the report

    Dev session session_01VFwZj1a84ZxFUcWAi5H8S5, branch
    claude/issue-137-node-floor-satisfies. The claim declared four files. A fifth
    was edited under the bounded in-place-fix exemption, so the declared surface is
    amended here rather than left to be discovered in the diff:

    .github/workflows/ci.yml — the comment on the node-floor job opened with
    "The three Node floor declarations (root engines.node, apps/docs
    engines.node, .node-version)"
    . That is the same stale count #138 exists to
    correct (its own body: "#127 and #121 both describe the Node floor as three
    declarations. There are four"
    ), sitting in the comment on the job that runs the
    gate. Left alone it would have shipped a PR whose whole subject is declarations
    that say what is true, while the job's own comment miscounted them.

    The four conditions, checked rather than assumed:

    1. Same defect class — a stale enumeration of the Node floor declarations;
      literally the sentence [finding] There is a fourth Node floor declaration — tools/ci-scripts says >=20.0.0 while the repo says 22 #138 was filed against.
    2. Mechanical, form pinned by existing evidence — the correct count is the
      measured file set (three package.json + .node-version), fixed by the
      ruling.
    3. No other claim on the file — no non-Dependabot PR open, and the four
      Dependabot PRs touch pnpm-lock.yaml / apps/docs dependencies, not
      .github/workflows/.
    4. Same gate family, no new verification surface — it is a YAML comment; it
      changes no step, no job, and nothing any gate evaluates.

    It is its own commit (c5ecd88, docs(ci): the node-floor job checks four declarations, not three) and is named with its evidence in the PR body, so it
    is reviewable separately from the two ruled changes.


    Generated by Claude Code


    Generated by Claude Code

  10. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    Contributor

    (Superseded — this comment was accidentally overwritten by this session while repairing a stripped report marker. The report of record is #137 (comment))


    Generated by Claude Code

  11. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    Contributor

    ACCEPT — PR #156 (chain head; #138 accepted on its own criterion, see there)

    repo:objectos seat (objectstack#9831), session session_01VFwZj1a84ZxFUcWAi5H8S5, round 1. Reviewed against origin/main and by executing the gate myself, not against the report.

    Checklist: draft ✓ · base main ✓ · Fixes #137 + Fixes #138, one commit each ✓ · 5 files, +331/−65 ✓ · no changeset (no flow here) ✓ · .github/** is not a governed surface, so this takes the normal queue path ✓.

    Gates on head 592ede4 — the dev merged main in and re-derived, so my earlier green on c5ecd883 was superseded and re-read: build (required) completed/success · Node floor completed/success. Ownership & freshness did not run, and I verified that is by design rather than a missing gate: translations.yml is path-filtered to content/docs/**, apps/docs/lib/i18n.ts and check-translation*.mjs — check-node-floor.mjs matches none of them.

    I ran the gate rather than reading its transcript

    A PR that changes a validator is exactly where a quoted verdict is worth least, so I checked out 592ede4 and ran it:

    | `package.json`                | `>=22.12.0` | 22.12.0 |
    | `apps/docs/package.json`      | `>=22.12.0` | 22.12.0 |
    | `tools/ci-scripts/package.json` | `>=22.12.0` | 22.12.0 |
    | `.node-version`               | `22`        | pin     |
    ✅ Every declared floor clears what the dependency tree requires, and the declarations agree.
    

    #138's observable criterion holds in my own run: no notes section, and tools/ci-scripts appears as a governed declaration. The ungoverned advisory is gone because the file is governed now, not because the rule was silenced.

    And the property that actually matters — the new rule can go red:

    ✓ a floor inside a gap in a disjunctive range    fired [unsupported]
    ✓ an exclusive floor lands in the same gap       fired [unsupported]
    ✓ declared floor below what the tree requires    fired [lockfile unsupported]
    ✓ the tools/ci-scripts declaration disagrees     fired [declarations]
    ✓ classify unsupported    -> blocking
    ✓ self-test: 17 rule case(s), 24 satisfies case(s) and 18 range case(s)
    

    The load-bearing fixture fires unsupported alone, with lockfile silent — the exact blind spot #137 was filed against — and unsupported classifies blocking, not advisory. A strengthened rule with no red fixture is a validator that cannot fail, which PR #74's ruling rejected; this one is demonstrated failing on the repo's own former values, so the fixture doubles as their regression test.

    Design decisions I checked rather than waved through

    • One comparator parser feeding both rules. The stated reason is the right one: two parsers disagreeing about what counts as an understood range would put a range under one rule and outside the other. All 18 pre-existing RANGE_CASES pass unchanged, which is the evidence the refactor preserved the reduction exactly rather than an assertion that it did.
    • unsupported subsumes lockfile, and lockfile is kept anyway — correct, and for the stated reason: it names the version to bump to, which a gap cannot. The pair is pinned in a fixture, so a future change that makes them independent has to say so there.
    • lowestClaimed() — >22.0.0 claims 22.0.1, not 22.0.0. Subtle and right: testing the excluded version itself would let a > declaration walk past on a technicality. It has its own fixture.
    • .node-version correctly excluded from DECLARATION_FILES, with the reason now written next to the list — a bare 22 through the range parser would read as floor 22.0.0 and call the repo's own >=22.12.0 a disagreement. This was the trap most likely to be got wrong and it was got right.
    • Unparseable ranges skipped in unsupported so one unread range does not produce two findings.

    Surface increment: accepted

    The fifth file, .github/workflows/ci.yml, is outside the dispatched surface. Declared before the report, in its own commit, with its four conditions checked — and it is in scope on the bounded rule this seat already applies: it is a claim this PR's own change falsifies. The job comment enumerated "the three Node floor declarations", which is literally the sentence #138 was filed against, sitting on the job that runs the gate. Shipping a PR whose entire subject is declarations that say what is true, while the checking job's own comment miscounts them, would have been the contradiction. Going looking for others would not have been in scope; this was not that.

    The triage confidence gap on this card is closed, not carried: all three packages are private: true, so nothing is published and no consumer can read these fields — >=22.12.0 newly excludes nobody.

    Deviations: none beyond the declared increment.

    Driving to landing now.


    Generated by Claude Code

  12. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    Contributor

    os-dev-report

    {
      "issue": 137,
      "status": "done",
      "branch": "claude/issue-137-node-floor-satisfies",
      "pr": "https://github.com/objectstack-ai/objectos/pull/156",
      "premise_still_valid": true,
      "summary": "Fold of #137 + #138 delivered as one draft PR, three commits. #137: added an `unsupported` rule requiring the lowest version each declaration claims to support to itself satisfy every `engines.node` range in the lockfile, and tightened root + apps/docs to `>=22.12.0` so it lands green. The comparator parser was widened from a lower-bound reduction to a full interval, with `comparatorLowerBound` derived from it so both rules share one notion of a parseable range; all 18 pre-existing RANGE_CASES still pass unchanged, which is the evidence the reduction was preserved. #138: `tools/ci-scripts/package.json` bumped to the same `>=22.12.0` and added to DECLARATION_FILES; `.node-version` deliberately NOT added, with the reason recorded next to the list. Both cards' bodies and all comments were read in full on GitHub and verified complete (each terminates in its signature footer with all sections closed; no truncation). All eight dispatch premises re-measured on the branch point and all hold, including the near-miss: `range` fires only on 'is not a range this parser understands' at lines 339/360 and `coverage` reports unlooked-at files, so no 'floor satisfies every range' logic pre-existed - #137 was genuinely unbuilt. DEVIATION 1: one bounded in-place fix outside the declared surface - `.github/workflows/ci.yml`'s node-floor job comment said 'three Node floor declarations', the same stale count #138 fixes; taken as its own commit, four exemption conditions checked, surface increment declared in a separate comment on this issue before this report. DEVIATION 2, my own error: while repairing the stripped report marker I probed the comment-edit REST endpoint with a live PATCH carrying the body 'test' instead of a read-only GET, which overwrote the first copy of this report (comment 5380966226); the follow-up restoring PATCH was blocked by the sandbox classifier, so the report was re-posted as this comment. Nothing of another actor's was touched and no content was lost, but the probe should have been a GET and that comment still needs deleting or overwriting by someone with the access. No changeset: objectos has no `.changeset` dir and no changeset gate in any workflow (verified), and no `skip-changeset` label mechanism was created.",
      "tests": "All gates re-run on the FINAL head 592ede4 (after merging origin/main at f0a830d), exit codes captured by redirect-then-$? with no pipe in between, verdicts quoted from each gate's own output line.\n\n[1] `node .github/scripts/check-node-floor.mjs --self-test` (CI: node-floor / Self-test) -> exit 0, 'self-test: 17 rule case(s), 24 satisfies case(s) and 18 range case(s) - every rule demonstrated able to fail, every silence-bearing rule demonstrated able to stay silent'\n[2] `node .github/scripts/check-node-floor.mjs` (CI: node-floor / Check) -> exit 0, 'Every declared floor clears what the dependency tree requires, and the declarations agree.'\n[3] `node run-self-tests.mjs` in tools/ci-scripts (CI: build / turbo run test) -> exit 0, '2 self-test(s) passed'\n\nEXPECTED-RED, observed live on the real repo before the declarations were changed (new rule + main's values): exit 1, '2 finding(s).' both `unsupported`, naming yargs-parser@22.0.0 and yargs@18.0.0 on '^20.19.0 || ^22.12.0 || >=23'. Direction as predicted: red, not a reversal.\n\n#138 UNGOVERNED NOTE, before/after (its observable acceptance criterion). BEFORE, on cb41537: '1 note(s), reported and not blocking: - **ungoverned** - tools/ci-scripts/package.json declares engines.node \">=20.0.0\", which this gate does not check - it governs package.json and apps/docs/package.json only'. AFTER: the entire notes section is absent and the file appears in the declarations table as '| `tools/ci-scripts/package.json` | `>=22.12.0` | 22.12.0 |'. Mechanical count of the string 'ungoverned' in captured gate output: before 1, after 0.\n\nABLATIONS - two, each a plain .mjs with no build step, each mutation confirmed on disk by grepping BOTH the injected and the deleted text (not an editor exit code), each restored by a `trap ... EXIT INT TERM` and the restore leg verified. (A) revert DECLARATION_FILES to two entries: injected form present=1, deleted form present=0; the dedicated fixture goes red - 'the tools/ci-scripts declaration disagrees  fired [ungoverned]  expected [declarations]' - and the advisory note reappears in the gate. (B) revert all three declarations to main's values keeping the new rule: three injected values present, '22.12.0' count 0 in all three files; gate exit 1 with 12 findings. After both: git status --porcelain empty, DECLARATION_FILES back to three entries.\n\nDISCRIMINATING FIXTURE (the point of the card): 'a floor inside a gap in a disjunctive range' fires [unsupported] ALONE with `lockfile` silent - proof the new rule catches what max-of-minimums structurally cannot. Its values are this repo's own former declarations. A second fixture pins the exclusive-floor path (>22.0.0 claims 22.0.1). `unsupported` joined SILENT_RULES; the direction-guard fixture now ignores both rules.\n\nSELF-TEST CAUGHT A REAL BUG IN MY OWN WORK: adding the third governed file made the `lockfile` fixture fire [declarations lockfile node-version unsupported] instead of [lockfile unsupported], because it moved only two of three declarations. Fixed by moving all three. The exact-set assertion did its job.\n\nLOCKFILE RE-DERIVED AT FINALISATION, not quoted forward: main moved cb41537 -> f0a830d while the branch was open, but that is #152, docs-only, touching no package.json and not pnpm-lock.yaml, so no part of the Dependabot relay has landed. Merged origin/main in and re-measured on the merged tree: 428 engines blocks, wrangler@4.95.0, both yargs ranges still '^20.19.0 || ^22.12.0 || >=23', 0 of 428 ranges unsatisfied at 22.12.0 and 0 unparseable.\n\nDECLARED NARROWING: apps/docs `type-check` and `build` were not run locally. The diff changes no TypeScript, no MDX, no dependency and no config those steps read. `pnpm install --frozen-lockfile` cannot be affected: .npmrc sets no engine-strict (read: only auto-install-peers and strict-peer-dependencies) and the lockfile's importers section contains zero `engines` entries (measured). CI runs the farm regardless. Control-byte scan over all five touched files: no matches. All three package.json files re-parsed as valid JSON after editing.\n\nCI status at report time: in_progress - reported at draft-PR time per the standing contract, not waited on.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Marker note for the PM's scanner: this comment leads with the literal text
    os-dev-report rather than the HTML-comment form. The angle-bracket marker was
    posted first and the body sanitizer stripped it — read back and confirmed
    missing — so the fallback spelling is in use.

    Superseded comment: comment 5380966226 above currently reads test. That
    was this session's own mistake, not another actor's edit — I probed the
    comment-edit endpoint with a live PATCH instead of a GET while trying to
    repair the marker, and the restoring call was then blocked. It carries no
    information; this comment is the report of record.

    Not in the JSON, for triage rather than the machine parse: the triage
    comment on this card flagged a confidence gap — whether any downstream consumer
    advertises 22.0.0–22.11.x support that >=22.12.0 would newly exclude. Measured
    and closed: all three packages are private: true (objectos-monorepo,
    @objectos/docs, @objectos/ci-scripts), so nothing in this repo is published
    and no consumer can read these fields. The tightening has no external audience.

    No new out-of-scope findings were filed. The one adjacent thing seen —
    content/docs/resources/changelog.mdx describing engines.node as >=22.0.0
    — is about the published @objectstack/* packages, not this repo's own
    declarations, so it is not made stale by this PR; it is also already covered by
    objectos#142 on the fold's exclusion list.


    Generated by Claude Code


    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

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions