Commit Graph
188 Commits
Author SHA1 Message Date
Chinesezjc f48596d2f7 Merge pull request #6863 from deepseek-harness/fix/weighted-approval-app-check
feat(ci): publish the approval decision label from a dedicated approval App
2026-10-22 16:47:28 +08:00
Chinesezjc 1e25d64a2e fix(ci): select decision runs by the publishing app
The App token cannot update a run the job token created and vice versa, so
selecting runs by `app.slug === 'github-actions'` missed every App run: each
phase created another run, a published App success was never revoked, and a
head with an older job-token run made the App patch fail. Select runs by the
publishing app slug instead, pass `vars.DSH_APPROVAL_APP_SLUG`, and set the
external_id marker on the setup-phase run too.

Cover the App-owned update and the job-run coexistence, and align the note with
the measured earliest-suite rule and the App slug variable.
2026-10-22 16:31:01 +08:00
Chinesezjc 7cf0362dce fix(ci): re-record the note pairing and keep the issue App assertion
The dedicated-App edit changed the note's decision section without re-recording
its translation sidecar, and the client-id replacement also hit the issue
lifecycle workflow assertion. Re-record the pair and restore the issue App's
variable names in that test.
2026-10-22 16:29:07 +08:00
imccyu 1276a8e13a ci: split pull-request CI into Linux, Windows, and Python workflows (#6898)
* ci: run native Windows PR jobs in a separate workflow

GitHub re-runs failed jobs only after a whole run finishes, so slow Windows jobs blocked re-running failed Linux jobs. CI Windows now owns the native Windows jobs and the Windows x64 Python runtime target, with its own required 'windows checks passed' verdict.

Refs #6893

* ci: run Python PR jobs in a separate workflow

Python rarely fails while the Windows lanes run long, so the Python SDK suite and the Linux/Windows x64 runtime matrix move into CI Python. The three pull-request workflows can now be re-run without waiting for each other, and branch protection gains "python checks passed" beside the existing verdicts.

Refs #6893

* docs: record the three PR verdicts in the failover runbook

* test: pin the shared environment across the PR workflows

* test: read the python SDK lane from CI Python

* test(sdk): parse session JSONL frames in the keyless smoke

Node 24.19 returned only the first frame of a concatenated zstd log, so the single JSON.parse saw just the header; 24.22 returns every frame and the JSONL body broke the parse. Read frames explicitly and select the main session by its header so both versions agree.
2026-10-22 04:09:35 +00:00
Chinesezjc 1665223358 feat(ci): publish the approval decision label from a dedicated approval App
Mint the check-run token from a dedicated approval App instead of a shared
automation App, so the identity that owns the decision check suite is specific to
this gate. The workflow reads `vars.DSH_APPROVAL_APP_CLIENT_ID` and
`secrets.DSH_APPROVAL_APP_PRIVATE_KEY`, and the token stays scoped to
`checks: write`.
2026-10-21 17:50:27 +08:00
Chinesezjc 5fc95b6213 feat(ci): publish the approval decision label from the repository App
The decision check run kept its job-token check suite out of the pull request's
merge box: GitHub associates check runs with a pull request through the check
suite of the workflow run, and a `pull_request_target` run is not associated.
Mint a token from the repository App scoped to `checks: write` and publish only
the check run with it, so the merge box lists the label; the commit status gate
keeps using the job token and is unaffected when the token or the write fails.

Pin the token step, its single secret reference, and the client split in the
workflow and approval tests, and record the measured association limit in the
Agent Note and review-ownership README.
2026-10-21 16:47:07 +08:00
Chinesezjc 82461b7f33 fix(ci): keep the weighted approval status unchanged and add the decision check run
Only add the `weighted approval decision` check run: the required
`weighted approval` commit status keeps its `pending`, `success`, and `error`
states exactly as before, and branch rules keep requiring it. The check run
reports the same decision as a conclusion label and is not required, so it
never blocks a merge.

The Agent Note and README now state the status semantics as unchanged and the
measured reason a required check run is not available here.
2026-10-20 19:44:13 +08:00
Chinesezjc e34162881c fix(ci): gate weighted approval through its commit status and label the conclusion
The required check run introduced previously is not matched by this repository's
branch rules, so the gate could not be satisfied. Keep the required
`weighted approval` commit status as the gate and publish the
`weighted approval decision` check run as the label: action_required while the
policy is unmet, success when it holds, failure on setup or evaluation errors.
The status completes as success or failure instead of waiting as pending, so CI
watchers end.

Record the measured check-run limit, the revocation and recorded-conclusion
design, and the alternatives in the Agent Note; update the review-ownership
README, the workflow permissions, and the approval tests.
2026-10-20 17:59:41 +08:00
Chinesezjc 4c293671ea Revert "Merge pull request #5440 from deepseek-harness/fix/weighted-approval-check-run"
This reverts commit 17c5ac9bac7eae975dde6596287deeb77cba20a4, reversing
changes made to c830699b0a3d21f993de79b2089f227da913e428.
2026-10-20 17:46:59 +08:00
Chinesezjc d98ff5d9fa fix(ci): gate the setup failure step on the recorded conclusion
The evaluation failure title was preserved by matching details_url, a field
GitHub may rewrite for check runs created with the workflow token, so the
setup-failure step could replace the specific title after all. Record the
conclusion the publish step wrote in a step output and run the setup-failure
step only when no conclusion was recorded; a published decision now survives
a later failure or cancellation without relying on an API field.

Record the measured timeout cancellation path and the re-run migration limit in
the decision note, and scope the pre-push guidance to ACTION_REQUIRED so a
failure conclusion is not read as an approval wait.
2026-10-20 15:01:34 +08:00
Chinesezjc 70b11f5f5f Merge remote-tracking branch 'origin/master' into fix/weighted-approval-check-run
# Conflicts:
#	.agents/notes/archived/process/2026-09-09-blocked-weighted-approvals-remain-pending.md
#	.agents/notes/archived/process/2026-09-09-blocked-weighted-approvals-remain-pending.zh.md
#	.agents/notes/implemented/process/2026-09-10-approval-review-workflow-identity.i18n.yaml
#	.agents/notes/implemented/process/2026-09-11-production-blame-approval-weight.i18n.yaml
#	.agents/notes/implemented/process/2026-09-15-pr-approval-delegation.i18n.yaml
2026-10-20 14:29:46 +08:00
Turtle 2099andturtle1999 14dcb78ee8 fix(ci): split the Wine Host compile to fit its heap budget (#6578)
The Wine gate compiled the Host face with one `tsc -b tsconfig.host.json`,
which holds the project-reference graph and the aggregate program in a
single V8 process and aborted at 4063.4 of 4088.3 MB. The supported build
splits those steps, and the native Windows build in the same run compiled
the references at 4096 and reached the aggregate without running out of
memory.

Compile the referenced projects first, then type-check the aggregate, both
at 4096. Assert the two commands and their order, and reject the fused
invocation.

Co-authored-by: turtle1999 <[email protected]>
2026-10-19 11:12:07 +00:00
Tianyi Cui 4d33f27225 Prepare metadata in public library builds 2026-10-18 14:29:23 +08:00
Tianyi Cui 9b310b2b4b Generate source metadata before package compilation 2026-10-18 14:29:23 +08:00
Tianyi Cui cfb65d3bb2 fix: validate the Node 24.9 runtime floor 2026-10-15 23:33:49 +08:00
Tianyi Cui c6a59a1ae9 build: require Node.js 24 or newer 2026-10-15 22:51:03 +08:00
imccyu 04af9a1df7 perf(build): generate Typert contracts without bundling for typecheck and lint
Type checks only need Host declarations and Typert-generated
declarations, but typecheck, lint, lint:fix, doc-typecheck, and the CI
typert-contracts gate rebuilt the whole Host tsdown pass, Desktop bundle
included, to obtain them. A source-only scripts/generate-typert.ts now
runs the same generator and artifact writer as the tsdown plugin, beside
Host package compilation: Typert reads only sources once the missing
@deepseek-ai/dsh-client-file-upload/types path alias exists, and
rejectBuildOutputs fails the pass when a workspace lib/ declaration
enters its program. typecheck runs as a build.ts scope that checks both
aggregates in build mode after their own face compiles.

Refs #5852
2026-10-12 11:06:49 +08:00
imccyu f6b0c5af59 build: rename build:src and build:test to build:artifacts and build:check
build:artifacts produces every artifact, including the tsdown bundles,
the Desktop bundle, and Web, so naming it after sources undersold it;
build:check checks scripts, benchmarks, and website code besides tests.
The build.ts scopes, aggregate step ids, the Python builder flag
(--build-artifacts), workflows, callers, docs, and the build-split Agent
Note follow the new names. The note also records the naming
alternatives.

Refs #5852
2026-10-11 22:16:47 +08:00
imccyu 129c915498 build: split build:src and build:test, and schedule build in parallel
pnpm run build ran every step in one serial chain, including the two
noEmit aggregate programs (tests, scripts, benchmarks, website) that no
artifact step consumes, so the Host aggregate check alone delayed tsdown by
about 66 s.

- build:src (scripts/build.ts --scope src) builds every artifact in the
  existing order and writes the client build record; it replaces the
  removed --artifacts-only flag and the libraries CLI mode.
- build:test (--scope test) type-checks only the Host and Client aggregate
  programs with tsc -p, concurrently, without compiling references or
  checking prerequisites.
- build runs both as one dependency graph through run-gates' new
  runAggregate: each aggregate check starts once its face's packages are
  compiled, and Client compilation stays after the Host bundle that writes
  the Typert /remote declarations. DSH_GATE_CONCURRENCY=1 serializes it;
  DSH_GATE_FAIL_FAST=1 stops the remaining steps at the first failure.
  Passing steps print one PASS line (DSH_GATE_VERBOSE=1 shows their output).
- PR artifact builds (e2e, release, preview, Node 22 compatibility) and the
  Python builder (--build-src) use build:src; dev:web and dev:desktop use
  build:src. test:*, bench, typecheck and the required consumer/Windows
  lanes keep the complete build.
- lint, lint:fix, doc-typecheck and the Typert contracts gate prepare with
  host-libraries (Host package compilation + Host bundle) instead of
  build:lib:host; their own checks never read the aggregate root or the
  Desktop bundle.

Parallel and serial build produce byte-identical lib/, Web dist and client
build record; a test-only type error fails build and build:test while
build:src passes.

Refs #5852
2026-10-11 18:19:23 +08:00
Yichen Jiang 1d0ede8c3a ci: trial larger GitHub macOS runners for Python releases 2026-10-11 14:00:17 +08:00
Yichen Jiang facdc69808 Merge remote-tracking branch 'origin/master' into worktree/ssh-helper-binaries
# Conflicts:
#	docs/config-catalog.i18n.yaml
#	docs/config-catalog.md
#	docs/config-catalog.zh.md
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/subsystems/ssh.i18n.yaml
#	package.json
#	packages/ptc-runtime/ptc-runtime-node/README.i18n.yaml
#	packages/ssh/README.i18n.yaml
#	packages/ssh/ssh/README.i18n.yaml
#	packages/ssh/ssh/package.json
#	pnpm-lock.yaml
#	scripts/build-exe-for-python-sdk.ts
#	scripts/verify-package-readme-model-experience.ts
2026-10-08 15:06:19 +08:00
turtle1999 0e7e2ceb19 ci(bench): warn on a missing benchmark report and document the artifact
The upload warns instead of silently ignoring missing files, and the spec
pins the upload after the benchmark step. benchmarks/AGENTS.md and the
report Agent Note now name the artifact CI publishes.

Refs #5840
2026-10-08 11:55:08 +08:00
turtle1999 a646dabbe9 ci(bench): publish the scaled benchmark report as an artifact
The node-24-bench job uploads benchmarks/.dsh-report after the benchmark
step, including when a budget assertion fails, so the report the Vitest
globalSetup renders survives the runner. #5838 deferred this step because
the authoring token had no workflow scope.

Refs #5838
2026-10-08 11:32:17 +08:00
Tianyi Cui 59bd530aaf chore(deps): update GitHub Actions to mature release tags 2026-10-07 22:28:27 +08:00
Tianyi Cui 5529a5014a fix(ci): skip the verification install when rebuilding Linux node-pty
pnpm 11.28.5 runs verifyDepsBeforeRun before a script, so `pnpm run install`
inside the installed node-pty directory first installed node-pty's own
dependencies into the package and ran its `prepare` build. Both reached the
packaged payload: the SEA blob then carried a node-gyp tree and tripled pkg's
file records, and postject aborted while injecting it. The step now runs the
package's install script alone, as it did with pnpm 11.7.0.
2026-10-07 13:10:09 +08:00
Tianyi Cui 9e9a95f8dc perf(ci): start runtime checks within the existing job ceiling 2026-10-05 18:21:54 +08:00
Tianyi Cui bbbe372f53 fix(ci): validate Python closure before artifact builds 2026-10-05 15:12:53 +08:00
Tianyi Cui fc072c7a5d perf(ci): bound worker job overlap without extending the critical path 2026-10-05 13:24:31 +08:00
Tianyi Cui 536aaef0b3 fix(ci): preserve workflow concurrency and portable artifact checks 2026-10-05 12:53:52 +08:00
Tianyi Cui 853ad0bb9f perf(ci): remove repeated aggregate compilation and gate work 2026-10-05 12:07:57 +08:00
Tianyi Cui 185b9c59e7 feat(release): support isolated npm channels 2026-10-03 09:20:13 +08:00
Tianyi Cui c7f66d13a6 docs(notes): prune redundant active decision records 2026-09-30 23:20:22 +08:00
Chinesezjc a0ed3981fe fix(ci): revoke the approval decision through its conclusion
A check run that reached completed never returns to in_progress: GitHub
answers 200 and leaves the run completed, so the revoke write was a
silent no-op on every re-evaluation and a published success survived an
interrupted setup or history fetch. Revoke a published success by
concluding it action_required, start a head that has no decision in
progress, and drop the status-only check-run update.

The setup-failure step ran only when the revoke step succeeded, so a
failed or cancelled publisher left the earlier conclusion standing. It
now runs on failure and on a cancellation that precedes the decision.

The decision note, the review-ownership README, and the two related
notes record the measured transition matrix and the fallback condition.
2026-09-30 13:42:02 +08:00
Turtle e5a010be64 Merge pull request #5403 from deepseek-harness/perf/session-corpus-benchmarks
test(bench): measure Session list, search, and fork over large corpora
2026-09-30 11:13:47 +08:00
turtle1999 094a8701fe Publish weighted approval as a completed check run
Unmet weighted approval conditions previously left a pending commit
status that CI watchers treat as running work, so gh pr checks --watch
and similar monitors never finished. Publish the decision as the
weighted approval decision check run instead: action_required blocks
merging while completing the check, and failure reports evaluation
errors.
2026-09-29 12:48:04 +08:00
Tianyi Cui f4d8115b4a merge: master into lane-budget-inline-projects
Resolves the semantic conflict with #5331: its ci-unit gate spread
coverageTestTimeoutArgs, which this branch retires; the gate is now a
plain vitest run and the darwin lane budget reaches vitest.config.ts
through the inherited DSH_COVERAGE_TEST_TIMEOUT_MS. The ci-unit spec
cases pin that shape under both budget values.
2026-09-28 23:25:21 +08:00
turtle1999 bfcd447963 test(bench): fit Session corpus benchmark within five minutes
Keep each case at its hardest setting that fits five minutes of hosted CI:
search and fork stay at 1,000 Sessions with the longest fork sampled once,
the list runs 3 samples over 3,000 Sessions, and seeding validates authored
bodies in memory instead of a separate verification pass. The file's last
case asserts the limit; the benchmark job timeout becomes 20 minutes.
2026-09-28 23:08:19 +08:00
turtle1999 e806d9cb97 test(bench): calibrate Session corpus budgets on hosted CI
Standard two-CPU hosted runs are 2.4-3.4 times the reference machine, above
the shared reference scale, so the budgets use rounded hosted medians with
the shared 1.25 headroom. The benchmark job took 14.4 minutes with these
cases; its timeout becomes 25 minutes.
2026-09-28 22:18:58 +08:00
turtle1999 d70efffb63 test(bench): measure Session list, search, and fork over large corpora
Add a required benchmark over synthetic corpora whose per-Session length
distribution is at least a measured local DSH corpus: list at 1,000 and
5,000 Sessions, cold and built content search and stratified forks at
1,000 Sessions, all through the real SessionController on built plain-Node
workers. Raise the benchmark job timeout to 30 minutes for the added cases.
2026-09-28 21:08:18 +08:00
Tianyi Cui 3e38e2118c test(vitest): make the lane-budget regression load-independent and own its resources
The fixture's poll case counts attempts instead of reading a clock, so a host
stall cannot turn a budget-ended poll into a pass; the control case reads the
poll's reported duration, which the 1000 ms default bounds from below. The
spawning spec acquires its temporary config in beforeAll, bounds the child
with a timeout and asserts no signal ended it, and counts the polled values it
inspects. CoverageTestTimeoutOptions is Vitest's own TestUserConfig members;
the rule's reach has one home in its JSDoc, which the config, gate, spec, and
note comments reference.
2026-09-28 14:18:03 +08:00
Tianyi Cui 333d7e75d2 test(vitest): apply the lane test budget inside every inline project
DSH_COVERAGE_TEST_TIMEOUT_MS expanded to --testTimeout, --hookTimeout, and
--expect.poll.timeout on the coverage and serial lanes, but Vitest forwards
only a fixed list of CLI overrides into inline projects and neither
hookTimeout nor expect is on it, so under the root config's two projects the
hook and expect.poll budgets stayed at Vitest's defaults on every lane.

vitest.config.ts now reads the variable through coverageTestTimeoutOptions and
spreads the three budgets into both projects; run-gates and the partition
coordinator pass no timeout flags, leaving one owner for the rule. A new spec
spawns vitest on the root config with a 200 ms budget and proves all three
waits end inside both projects, that unset keeps the defaults, and that a
malformed value fails at config load.

Fixes #5335
Related to #5325
2026-09-28 13:37:20 +08:00
Tianyi Cui 9ab3f2c990 ci(sandbox): grant the darwin unit parity job the coverage lanes' test budget
The unit-darwin job ran the whole unit inventory at Vitest's 5000 ms default
on a shared 3-vCPU macos-latest runner; the first two master runs after #5292
each timed out a different set of cases that pass in under a second on a quiet
host. Every other whole-inventory lane raises the budget through
DSH_COVERAGE_TEST_TIMEOUT_MS=90000.

The job now sets that variable and runs `pnpm run check:ci:unit`, a run-gates
aggregate that is `pnpm run test` (native build, then `vitest run`) through the
path that consumes it. ci-unit receives no CI worker settings, so the inventory
inherits the environment `pnpm run test` finds: on a 3-CPU host the defaults
would inject DSH_COVERAGE_PARTITIONS=2, which run-gates.spec.ts reads as a
partitioned coverage lane.

Fixes #5325
2026-09-28 12:58:10 +08:00
Yichen Jiang 11c58d11b9 fix(ssh): build helper executables only on manual requests 2026-09-23 19:52:50 +08:00
Yichen Jiang d9342fcb5d feat(ssh): package standalone POSIX helper runtimes 2026-09-23 19:16:59 +08:00
Tianyi CuiandLegGasai 766e6f9176 test(ci): reject prunable Ubuntu bubblewrap URLs
The merged dependency repair in #4589 uses a recorded Launchpad build,
but #4591 also requires a regression guard against restoring the live
Ubuntu package pool. Those pool URLs disappear when versions are
superseded, even when the content digest is pinned.

Adapt LegGasai's URL guard from closed PR #4590 to the build-specific
endpoint that landed in #4589. Check the endpoint structure without
copying the current build number, version, or checksum into the test,
and reject Ubuntu pool downloads anywhere in the script so adding a
pool fallback cannot bypass the guard.

Negative controls restore the original archive URL and inject security
and ports pool fallback URLs; each fails the new guard. The original
script is restored byte-for-byte before all 44 workflow tests pass.
This adds only a static regression test, with no network calls or
changes to the download script or CI execution behavior.

Co-authored-by: LegGasai <[email protected]>
2026-09-19 12:08:11 +08:00
Yichen Jiang ed50586256 refactor(ci): remove unused Windows observational entry 2026-09-18 14:27:45 +08:00
Yichen Jiang 235db2a031 Merge remote-tracking branch 'origin/master' into worktree/windows-observational-reuse
# Conflicts:
#	.github/workflows/ci.yml
2026-09-18 14:13:26 +08:00
Turtle 5459be6656 ci: halve core-seconds in static and Windows observational lanes (#4521)
* ci: trial smaller Blacksmith static and observational runners

* ci: measure the 16-vCPU control for runner sizing

* ci: use 4-vCPU static and 8-vCPU observational runners

* ci: retain 8-vCPU static runner for completion time
2026-09-18 14:01:46 +08:00
Yichen Jiang a116bf73c6 Merge master and name combined Windows checks 2026-09-18 13:41:06 +08:00
Turtle 9d5fc30632 ci: adapt concurrency to available runner CPUs (#4518)
* ci: adapt worker pools to available runner CPUs

* ci: preserve local snapshot worker defaults

* test: isolate CI worker overrides in gate fixtures

* docs: clarify shared Windows worker limits
2026-09-18 13:17:34 +08:00