Repository navigation
Description
Split out of #14639 by triage. That card is the current instance — four fixable OSV advisories red in the lockfile — and is queued as a take-the-fix repair. This card is the question it records but deliberately does not answer: why this class keeps being discovered by accident.
The measured lineage (from #14639, which assembled it)
| Card | Advisory | Disposition |
|---|---|---|
| #4945 | brace-expansion | closed, took the fix ("cleared in ten minutes") |
| #5032 | undici / hono / fast-uri, 8 fixable, red on main |
closed |
| #5039 | fast-uri / hono / undici, "队列级阻塞" | closed |
| #6407 | dompurify via mermaid | closed |
| #6506 | nanoid, "有 fix,缺 override" | closed |
| #14639 | @xmldom/xmldom ×2, qs ×2 | open |
Six in a month. Every one was fixable at the time it was found. Every one was found by whichever seat happened to trip over it, never by anything watching.
The mechanism
.github/workflows/validate-deps.yml runs on two triggers that do different jobs and are not synchronised:
schedule: cron '0 3 * * 1'— weekly, Mondays. This is the discovery trigger.**/package.json,pnpm-lock.yaml,.changeset/config.json,pnpm-workspace.yaml,osv-scanner.toml— per-PR. This is the blocking trigger.
Between Monday scans, a new advisory lands in the OSV database and nothing in the repo changes. The first PR that touches any manifest then runs the scan and eats a red that has nothing to do with its diff. So the blocking trigger is doing the discovery, six days late, on a random author.
Options
- A — tighten the scan cadence (daily rather than weekly). Discovery moves ahead of blocking without adding anything new. Does not change who acts on it.
- B — give the scheduled scan an outlet: a red scheduled run opens a card. The job already holds
issues: write, so the capability is present and unused. - C — status quo. Keep discovering by collision. Six data points say what that costs.
A and B are not exclusive.
What this card does NOT cover
⛔ The four current advisories. Those are #14639's, and that card is pm:queue — do not fold the repair in here, and do not wait for this ruling to take the fix.
<!-- os-decision-facets -->
- ① 项目长远合理性(权重 ≥50%,领起推荐) —— 平台有两道触发器:一道每周扫一次(负责发现),一道对每个碰 manifest 的 PR 生效(负责阻塞)。两者之间有六天的窗口,于是阻塞那一道在替发现那一道干活 —— 而且是在一个跟这件事毫无关系的作者身上。长远终态很朴素:发现要早于阻塞。①指向「让定时扫描的红有一个出口」,而不是继续让下一个提 PR 的人充当探测器。
- ② 实际业务拉动 —— 一个月六次,每次都是「某个席位恰好撞上」,而且每次都跨车道。这是已测的、重复发生的代价,不是假想。
- ③ 防 AI 犯错 —— 出错时谁看到什么:一个 agent 提了个只加一行
scripts的 PR,CI 红了,红的原因跟它的改动毫无关系。它会去读 OSV 报告、可能去动锁文件、甚至可能去osv-scanner.toml加豁免 —— 而那个文件的规则明令有 fix 时禁止豁免。⚠️ 把不相关的红扔给最不该修它的人,正是最容易诱发错误修法的形状,而这里连正确的修法都写在一个它未必会读的文件头里。 - ④ 创业阶段不扩散 ——
⚠️ 这一棱反对 B:自动开卡是往 backlog 里新增一个自动生产者,而生产者集合是有永久代价的 —— 每张自动卡都要被分诊、去重、关闭,而这正是本席这个座位的负载。提频(A)不新增生产者,只是把同一条信号提早。④明确偏 A。
推荐:A —— 先提频到每日,不自动开卡。 ②有重复拉动、③要的是提早发现,提频就足以给到;④明确反对新增自动生产者;①两者都满足,而 A 更便宜。
回退:B —— 若维护者判定「提频只是让红更早出现,而没有人负责去看」,那就给定时扫描一个出口(该 job 已持有 issues: write)。代价必须同批裁定:自动卡的去重规则、关闭规则,以及它算不算 finding 箱的输入 —— ⛔ 否则它会变成一个没有人负责清空的第二条队列。
⛔ 不荐 C。 六次是已测数据。
置信缺口(本分析看不见什么): 没有量提频后的噪声 —— 每日扫描会不会在同一条未处理的通告上连续红七天,取决于谁在看 scheduled run 的结果,而「谁在看」本轮没量。这是 A 唯一可能不成立的地方,也正是 B 想解决的那件事。
Refs: #14639 (the current instance, and the card that assembled this lineage) · #4945 · #5032 · #5039 · #6407 · #6506.
Generated by Claude Code
Activity
os-project-manager commentedon Sep 3, 2026
Maintainer ruling recorded — A: the OSV scan runs daily; no automatic card producer yet
Director seat, summon #11, session
session_01ShyhexkB2d1AeRZ85tgAAe, 2026-09-03.Provenance (who / verbatim / where): maintainer, live PM chat with the director seat, 2026-09-03, replying to decision batch #20 in which this card was item 5 with the recommendation A (fallback B). Verbatim reply: 「其他同意」 — adopts A.
Ruled: A. The
osv-scanner.ymlschedule moves from weekly to daily (one cron line), so the discovery window for a new advisory shrinks from up to six days to one and a seat is far more likely to see the scheduled red before an unrelated PR collides with it. Option B (a scheduled red opens a card automatically) is not built now: it is a new automatic producer whose dedupe and close rules would have to be ruled with it, and the measured pull (six collisions in a month) is answered by the cadence first. Recorded fallback: if a daily red is measured going unseen until a PR collides with it, B returns as its own card with the dedupe / close rules in the same proposal.Execution:
domain:devxlane, S,.github/workflows/osv-scanner.yml;skip-changeset;Clause-②: no.State transition, same stroke:
needs-user-decision→pm:queue. Ledger: director seat post #12708, summon #11.Generated by Claude Code
claude commentedon Sep 3, 2026
Claim: PM loop round 1
Session:
session_012zGPuVVX3deAx9LdjK8jCkBranch:
claude/issue-14645-osv-daily-cadenceWorktree:
objectstack-issue-14645Domain:
domain:devxFile surface:
.github/workflows/validate-deps.yml(stop on breach; explain in the report)Container & model: S mechanical,
mode:subagent,model: sonnet(dispatch-gates--tierat 11:02Z: no path-derived mandate; floor sonnet applies — one cron field, correctness judged by the gate farm)Clause-②: no
Serial constraints cleared:
none— no in-flight devx card touches.github/workflows/**; verified against the four live PRs #14853/#14872/#14896/#14856, whose ten pairwise file intersections are all 0Generated by Claude Code
baozhoutao commentedon Sep 3, 2026
Claim (dev agent): starting implementation.
Session:
session_012zGPuVVX3deAx9LdjK8jCkBranch:
claude/issue-14645-osv-daily-cadenceWorktree:
../objectstack-issue-14645Note: the ruling names
.github/workflows/osv-scanner.yml, which does not exist onorigin/mainat my base commit450e73b. The card body correctly names.github/workflows/validate-deps.yml(schedule cron on line 22,issues: writepresent). Applying the ruling's substance — weekly → daily, one cron line — to that file, per the card's own correction note.Generated by Claude Code
Generated by Claude Code
ci(deps): tighten OSV/dependency scan schedule from weekly to daily
baozhoutao commentedon Sep 3, 2026
os-dev-report
{ "issue": 14645, "status": "done", "branch": "claude/issue-14645-osv-daily-cadence", "pr": "https://github.com/objectstack-ai/objectstack/pull/14934", "premise_still_valid": true, "summary": "Moved the OSV/dependency-scan schedule trigger in .github/workflows/validate-deps.yml from weekly ('0 3 * * 1', Mondays) to daily ('0 3 * * *'), same 03:00 UTC hour — Option A per the maintainer ruling (issue comment 5523306978). The ruling names .github/workflows/osv-scanner.yml, which does not exist on origin/main; applied the ruling's substance to validate-deps.yml, the file the card's own body correctly names and which actually carries the schedule trigger and issues: write. Did not build Option B (no issue-opening step added) and did not fold in #14639's four advisories, per scope fence.", "tests": "HEAD 663dc667 (matches pushed branch tip). All 29 commands dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived from this changeset ran via scripts/pm/os-verify-lock.sh, foreground, exit code captured before any pipe (redirect-then-$?-then-read pattern), each read from its own printed verdict line, all exit 0: check-aggregator-roster, check-changeset-fixed, check-closing-keyword-parity, check-comment-mask-corpus (5790 files, 0 disagree), check-osv-exemptions (--self-test + real run), check-position-name-fold-loaders, check-required-contexts, check-self-test-wired, check-self-test-workflow-commands, check-shard-attestation, check-step-collectors, check-whole-set-label-write, docs-audit/check-drift-comment, pm/ci-failure --self-test, check:agent-test-spelling, check:declared-population-live, check:node-version, check:nul-bytes, check:override-consistency (9 override(s) resolve to targets), check:pm-dispatch-gates (dispatch-gates self-test: 1288 cases pass), check:pnpm-acquisition, check:pnpm-filter-targets, check:refd-timer-probe, check:required-contexts, check:shard-attestation, check:stall-guard-budget, check:stall-guard-headroom, check:watch-hint-literal, check:workflow-status-functions (30 workflow files, 53 jobs). Re-derived the family list post-commit at HEAD 663dc667 (dispatch-gates.mjs --commands again): identical list, no new gates introduced by the final commit. YAML validated with python3 yaml.safe_load. On-CI (informational, not waited on beyond what completed during this turn): PR #14934 checks — 'Validate Package Dependencies' (validate-deps.yml itself, pull_request trigger) succeeded; 27 of 30 check runs completed successful/skipped; 'Lint & Repo Gates' was still in_progress when this report was written (in_progress, CI convergence is PM's to track per dispatch instructions, not re-polled here).", "mcp_calls": 10, "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
claude commentedon Sep 3, 2026
ACCEPT — PR #14934, reviewed 2026-09-03T11:24Z by
session_012zGPuVVX3deAx9LdjK8jCkChecked against the diff and
origin/main, not the report.main, first lineFixes #14645,skip-changeset+size/xs.github/workflows/**is explicitly NOT governed (docs/adr/**·.claude/**·skills/**·AGENTS.md·CLAUDE.mdis the whole list) ⇒ normal ready→queue path.github/workflows/validate-deps.ymlonly- cron: '0 3 * * 1'→+ cron: '0 3 * * *'— one field, same 03:00 UTC hourThe judgement call in it that was right
The dispatch asked for "one cron line". The dev also rewrote the adjacent comment — which reads as scope creep for about two seconds, and is in fact the correct minimum: the old comment said "Run weekly on Monday at 03:00 UTC". Changing only the cron would have left a comment asserting weekly directly above a daily schedule — a fresh declared ≠ enforced contradiction, in the same three lines, introduced by a card whose whole subject is discovery lag. The four added lines say what changed and why, and cite the card. ⇒ Correct, not creep.
The ruling's filename slip, handled the way I asked
The ruling names
.github/workflows/osv-scanner.yml. That file does not exist — I measured this at 11:01Z before dispatching, and the dev re-measured it independently. The ruling's substance (weekly → daily) was applied tovalidate-deps.yml, the file the card's own body names and the one that actually carries both theschedule:trigger andissues: write. ⛔ Nothing was re-adjudicated; the slip is clerical and is recorded in the PR body.Gates
29 dispatched families derived by the dev from its own tree post-commit and re-derived at the final HEAD (identical list — so no gate was introduced by the last commit and then left unrun), all exit 0, captured before any pipe by the redirect-then-
$?-then-read pattern. YAML re-validated withyaml.safe_load, which is the one check that matters for a workflow edit and is not implied by any of the 29.Landing — not yet armed, deliberately
CI on
663dc6670fat 11:23Z: 17 success / 12 skipped /Lint & Repo Gatesstillin_progress. Enqueue eligibility is every check green, not the required subset, so this waits. Flip + arm on convergence; a red there is this PR's to explain, not to re-run.Generated by Claude Code
claude commentedon Sep 3, 2026
LANDED — PR #14934 MERGED 12:01:13Z; probe on
origin/maindomain:devxseat, sessionsession_012zGPuVVX3deAx9LdjK8jCk, R1.Merge commit
3210b3d5dconfirmed an ancestor oforigin/main(git merge-base --is-ancestor, exit 0). Option A as ruled; ⛔ no Option B producer built; ⛔ #14639's advisories untouched.cron: '0 3 * * 1'— weekly. The change had not reverted: my localorigin/mainref was fetched before the 12:01:13Z merge.origin/mainis a local ref that only afetchmoves, and a merge notification does not move it. Re-fetch before every post-merge probe; without that step this close-out would have reported a landed change as missing.ACCEPT:
5524960911.pm:dispatchedstripped, assignee cleared.Generated by Claude Code
ci(deps): tighten OSV/dependency scan schedule from weekly to daily (o…