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
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
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 (#22189requires, #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")
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.
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.
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.
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.
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.
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/mainc91544a4: 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
{
"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."
]
}
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.
Activity
objectstack-fleet commentedon Oct 25, 2026
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.
packages/lintisdomain:specby the anchoring rule. A lint arm of the stated range grammar, not a new gate: it runs in the existingos lint/os validatedoors.Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
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:queuewhen #25792 closes; nothing else about the card changes.objectstack-fleet commentedon Oct 27, 2026
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).dependency_missing, 422) at the three install doors, plus dependency-declared namespace co-owners and the dependency-ordered rehydrate #25792 closedcompleted. Its dependency-range reader is onmain, so ADR-0141 D2's "never a second reader" is now satisfiable. The author-side lint reuses that reader, ⛔ it does not re-parse the grammar. The dev names the reader's export on the claim head.436d284069) retiredPackageDependency.optionalandAppManifest.dependenciesat 2026-10-27T02:42Z. Read the current manifest shape before writing the lint arm.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 1 · 2026-10-27T05:18Z
Session:
session_01WGufzfhobWEgUUrjz4rrbhAccount:
os-support-aiBranch:
claude/project-thread-qdyxhg(card threadsession_01WGufzh15CRsSoQWL9C3Uja. The platform assigns the thread's branch and the thread can push only that one, so the branch is written as measured instead ofclaude/issue-25793-<slug>.)Worktree:
objectstack-issue-25793Domain:
domain:specSeat:
domain:spec#1File surface: a new
packages/cli/src/utils/dependency-range-check.tsand its test, the call sites inpackages/cli/src/commands/validate.ts,compile.tsandlint.ts, oneSHARED_NON_REGISTRY_GATESrow inpackages/cli/test/validate-build-gate-parity.test.ts, and one patch changeset for@objectstack/cli. ⛔ Nopackages/metadata-corechange. Stop on a breach and explain it in the report.Container & model:
S,mode:thread,model: TIER_DEFAULT, default effortClause-②: 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/mainc91544a4:checkDeclaredDependenciesandDEPENDENCY_RANGE_GRAMMARare exported frompackages/metadata-core/src/protocol-handshake.ts,@objectstack/clialready 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
objectstack-fleet commentedon Oct 27, 2026
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
objectstack-fleet commentedon Oct 27, 2026
Landed ·
domain:specseat 1 (#6017) · sessionsession_01WGufzfhobWEgUUrjz4rrbh· 2026-10-27T06:59ZPR #26505 merged at
48ee8b6d(merged 2026-10-27T06:59Z).48ee8b6dis an ancestor oforigin/main. On every path the PR touched, the merge tree matches the accepted heade61d8355byte for byte.os validate,os buildandos lintnow reportmanifest.dependenciesranges 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-recorddependencies. 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 throughFixes #25793, and this seat removespm:dispatched.