Skip to content

ADR-0141 author side: os lint / os validate report a dependencies range outside the stated grammar and an in-artifact co-delivered range mismatch #25793

Closed

Description

@objectstack-fleet

Blocked-by: #25792

Filing gate: ③ maintainer-directed — the author-side card ADR-0141 §Execution plan item 2 names, owed by landed work (PR #25717, merge afe6ab9ccc)
Ruling: #25403 comment 6369704387 (B′, maintainer 「同意」 2026-10-23T16:28:30Z) — the pre-install check refuses "with a clear message"; ADR-0141 D2 records that the install refusal is the backstop, not the place an author first learns the range grammar
Business reason: an app author splitting a product into modules (HotCRM first, hotcrm#2271) should hear about an unreadable dependencies range, or a module whose declared range its sibling's version does not meet, at build — not from a tenant administrator whose install was refused. Without this card the first signal is a 422 in someone else's environment, and an in-artifact mismatch is never reported at all (D2 judges a co-delivered dependency for presence only).
Reader: the packages/cli / packages/lint lane, one PR beside packages/cli/src/utils/protocol-version-gap.ts#checkProtocolVersionGap (the engines.protocol reading os validate already performs)
Dedupe (open AND closed): "dependencies range lint os validate semver range manifest dependencies" → 5, none on a dependencies range (#22189 requires, #17069 empty stack, #15986 / #5032 / #4965 npm deps); "pre-install dependency check dependency_missing install refuse missing dependency" → 0
Size: XS. Order: released with or before the runtime card #25792 (ADR-0141 item 1), so the first refusal an author meets is at build. It reads the range with the runtime card's reader; if this card goes first, it lands that reader (the sibling function in packages/metadata-core/src/protocol-handshake.ts) and the runtime card reuses it — ⛔ never a second reader.

What to build (ADR-0141 D2, last paragraph of "The range reader, and the grammar it must state")

  1. A rule that reports a manifest.dependencies value outside the stated grammar (at least ^, ~, >=, an x wildcard, || and the space intersection), naming the entry and what was unreadable.
  2. Inside one artifact (ADR-0130 multi-package), a rule that reports a co-delivered entry whose range the sibling package's declared manifest.version does not satisfy (e.g. core bumped to 2.0.0 while a module still declares ^1.0.0). The install never reports this one (D2: presence only), so this is its only reporter.
  3. Both under os lint and os validate on the ADR-0130 D4 union fold (the multi-package stack, not the top level alone; os validate and os lint judge an EMPTY stack when a project declares its metadata only in packages[] — the ADR-0130 D4 union fold (authoringRuleUnionStack) is wired into os build alone #17069 is the precedent for that trap).

Out of scope

Judging whether an out-of-artifact dependency is installed or in range — os validate cannot see the target environment (ADR-0141 §Consequences); that is #25792's install check.

Activity

  1. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — enhancement · priority:p2 · domain:spec · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T13:53Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • Ruled (ADR-0141 §Execution plan item 2). packages/lint is domain:spec by the anchoring rule. A lint arm of the stated range grammar, not a new gate: it runs in the existing os lint / os validate doors.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 26, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked-by: #25792

    Parked by domain:spec seat 2 at the round-1 dispatch: ADR-0141 D2 allows one dependency-range reader ("never a second reader"). #25792 (dispatched on domain:server) adds that reader to packages/metadata-core/src/protocol-handshake.ts on an unmerged branch, so the author-side lint must reuse it after it lands. The card goes back to pm:queue when #25792 closes; nothing else about the card changes.

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: unlocked · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T03:59Z

    ⛔ Not a claim, ⛔ not a dispatch. pm:blocked → pm:queue; the grade stands (p2 · domain:spec).


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-27T05:18Z
    Session: session_01WGufzfhobWEgUUrjz4rrbh
    Account: os-support-ai
    Branch: claude/project-thread-qdyxhg (card thread session_01WGufzh15CRsSoQWL9C3Uja. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead of claude/issue-25793-<slug>.)
    Worktree: objectstack-issue-25793
    Domain: domain:spec
    Seat: domain:spec#1
    File surface: a new packages/cli/src/utils/dependency-range-check.ts and its test, the call sites in packages/cli/src/commands/validate.ts, compile.ts and lint.ts, one SHARED_NON_REGISTRY_GATES row in packages/cli/test/validate-build-gate-parity.test.ts, and one patch changeset for @objectstack/cli. ⛔ No packages/metadata-core change. Stop on a breach and explain it in the report.
    Container & model: S, mode:thread, model: TIER_DEFAULT, default effort
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a. This is the author-side card owed by ADR-0141 §Execution plan item 2, not a defect card.
    Thread-read: none
    Premise: holds (read at origin/main c91544a4: checkDeclaredDependencies and DEPENDENCY_RANGE_GRAMMAR are exported from packages/metadata-core/src/protocol-handshake.ts, @objectstack/cli already depends on @objectstack/metadata-core, and the blocker #25792 closed as completed via #26401)
    Serial constraints cleared: yes. No open PR or claim names these files. ADR-0141 D2's single reader is reused, never re-parsed. Severity follows the install's own verdict: error only where the install refuses, and warning where it admits.
    Ruling-ref: #25403 comment 6369704387 (B′, maintainer 「同意」), ADR-0141 D2

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 25793,
      "status": "done",
      "branch": "claude/project-thread-qdyxhg",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/26505",
      "session": "session_01WGufzh15CRsSoQWL9C3Uja",
      "premise_still_valid": true,
      "summary": "os validate, os build and os lint now judge every manifest.dependencies entry of the packages one install act delivers (packages[] bodies, else the top-level manifest), through @objectstack/metadata-core checkDeclaredDependencies (export named; DEPENDENCY_RANGE_GRAMMAR for message text). No grammar is re-parsed and metadata-core is unchanged. Each package is judged alone with its siblings standing in for the registry, so out-of-range is the in-artifact mismatch (arm b) and unreadable-range is arm a. Severity follows the install verdict: error only for an unreadable out-of-artifact range or a non-record dependencies (refused in every environment); in-artifact findings are warnings, because the install admits them (presence only). New packages/cli/src/utils/dependency-range-check.ts beside protocol-version-gap.ts; wired in validate.ts step 3e, compile.ts step 3b-quater, lint.ts lintConfig; parity roster row added. Card assignee was already os-support-ai; PR assignee mirrors it.",
      "tests": "At 8f126e6f..d93a2217: src/utils/dependency-range-check.test.ts plus test/validate-build-gate-parity.test.ts gave Test Files 2 passed, Tests 43 passed. The install-door agreement pin (4 stacks: errors equal the install door's environment-independent refusals) is inside it. Door test test/dependency-range-doors.test.ts --project integration: 5/5 passed. Whole cli unit tier: Test Files 336 passed and 2 failed, Tests 4890 passed and 29 skipped. The 2 red files were published-subpath-console.pin and published-subpath-hook-body.pin, which failed with 'packages/cli is not built'. After pnpm --filter @objectstack/cli build they pass: 2 files, 29 tests. Ablation via scripts/ablation-replace.mjs on dependency-range-check.ts, anchor severity: inArtifact ? 'warning' : 'error' changed to 'warning'. The anchor went 1 to 0 and the blob 6da446f5da80 to a6cf785ecc76. Result: 3 failed and 12 passed (both arm-1 error tests and the out-of-artifact agreement pin). Restored: blob equals HEAD and git diff HEAD is empty. The tests import src, so no dist leg applies.",
      "gates": "Local, at d93a2217 (the run began at 8f126e6f; d93a2217 changes one type cast in a test): pnpm --filter '@objectstack/cli^...' build gave VERDICT command-exit 0. pnpm --filter @objectstack/cli build && typecheck gave VERDICT command-exit 0 (check:test-typecheck OK). eslint --no-inline-config on the 7 changed files: exit 0. dispatch-gates --commands derived 62 families, run serially, exit codes captured before any pipe. dispatch-gates --ran: 62 accounted, 57 run, 5 NOT MEASURED derived from exit 3 (prerequisite: a full build or a pinned fixture commit): check:i18n, check:i18n-coverage, check:i18n-walk-parity, check:dual-build-cjs-loads, check-plugin-teardown-shape --self-test. CI on PR 26505 at report time: 'No other open PR may claim the same issue' success. Every other check (Lint, Type Check, Check Changeset, Governed Surface Queue Guard, the card-claims-branch check, Check PR Size) was in_progress. Test Core, Build Core and the UI lanes had not been listed yet. test:repo is not run locally and is left to CI.",
      "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "4: issue_read get, issue_read get_comments, pull_request_read get_check_runs, and this report's own read-back. All are reads.",
      "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches each). Stroke 1: pr_create, which made POST /pulls and POST /issues/26505/assignees. Stroke 2: pr_request_reviewers (POST /pulls/26505/requested_reviewers, os-support-ai, per the project's attribution rule) and comment (POST /issues/25793/comments, this report). Plus 3 git pushes, which are not REST writes.",
      "open_questions": [],
      "out_of_scope_findings": [
        "none: no defect, contract violation or authoring trap found on the way. The card's 'union fold' wording is noted in the PR's Acceptance notes: the check reads packages[] bodies, the install door's reading."
      ]
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:spec seat 1 (#6017) · session session_01WGufzfhobWEgUUrjz4rrbh · 2026-10-27T06:59Z

    PR #26505 merged at 48ee8b6d (merged 2026-10-27T06:59Z). 48ee8b6d is an ancestor of origin/main. On every path the PR touched, the merge tree matches the accepted head e61d8355 byte for byte.

    os validate, os build and os lint now report manifest.dependencies ranges at build time through the install's own predicate (checkDeclaredDependencies). An error is raised only where the install refuses: an unreadable out-of-artifact range, or a non-record dependencies. Everything the install admits is a warning, such as an in-artifact mismatch. The diagnostics use kebab-case codes (ADR-0112 D6c). The card closed through Fixes #25793, and this seat removes pm:dispatched.

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:specenhancementNew feature or requestpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions