Skip to content

chore(integration): combine reviewed issue fixes - #406

Closed
Haoming9527 wants to merge 82 commits into
mainfrom
work/reviewed-integration-20261025
Closed

Haoming9527 wants to merge 82 commits into
mainfrom
work/reviewed-integration-20261025

Conversation

@Haoming9527

@Haoming9527 Haoming9527 commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

What was wrong

The issue fixes were individually reviewable, but they shared lifecycle code, configuration contracts, workflows and changelog insertion points. Separate green PRs did not establish that the complete set worked together. The integration branch had passing combined validation but no pull request for reviewing that combined result.

The change

Combine the original commits from #344, #381, #383 and #388–#405 into one integration draft targeting main. Preserve contributor history and prerequisite ancestry. Changelog insertion conflicts retain both sides; the only workflow conflict was explanatory text. Source files merged without textual conflicts. This aggregate introduces no additional feature implementation beyond the linked slices and their reviewed conflict resolutions.

This is an aggregate review draft: its combined diff exceeds the repository's approximate 1,000-line implementation slice limit. The individual PRs remain the bounded review units. Opening this draft does not merge or close them.

Area Included review units
Audit-store protection, checksums, bounded grep and catalogue contracts #344, #388, #393, #394
Incremental sessions, append-time publication, host metadata and stalled-probe isolation #383, #390, #395, #405
Bash IPC, terminal presentation, stdin/PATH and JSON spill summaries #389, #391, #392, #396
Migration, macOS Intel and host integration guidance #397, #398, #400
Benchmark reports, portability, routing conditions and component switches #381, #399, #402, #404
PR CI coverage and bounded review snapshot CLI #401, #403

The original dependency paths remain #383 → #390 → #405, #391 → #396, and #381 → #399 → #402 → #404. PR #404 also includes #401's all-target CI change.

Keep #261, #207, #303 and #360 open. Draft / NO-MERGE #362 is excluded. Administrator enforcement, Desktop restart/new-session validation and the controlled #360 model benchmark remain deferred. The #356 implementation is its CLI-first P0 slice; later phases and causal savings claims are not included.

Validation

Verified head: 2e261035f88780015a7e132d36e7614e6cf4a8de. Verified main: 662a38871f2241886343090adda0a1107a50e274.

Combined branch workflow 40115118596 passed all 12 jobs: Windows, Linux, macOS arm64, macOS Intel, Node-floor, workflow lint, source size, tools trial, three model-free benchmark smoke platforms and CI required. Its event was workflow_dispatch; it is branch-integration evidence, not a substitute for this PR's own event run.

This PR's own pull_request CI run 40116812179 completed successfully at the same head: 9 executed jobs passed (Linux, Windows, macOS arm64, macOS Intel, Node floor, workflow lint, source size, tools trial, CI required) and the conditional benchmark smoke was skipped as expected. The earlier dispatch remains separate branch-integration evidence, not a substitute for this event run. The draft remains unmerged.

Local combined checks:

npm run build
  TypeScript compiled; browser modules and PTC declarations built.
node scripts/check-workflows.mjs
  all 89 checks passed
node scripts/validate-manifest.mjs
  all 133 checks passed
node scripts/check-file-size.mjs
  426 code files checked, all at or under 1000 lines
node test/run.mjs bench- probe-isolation review-snapshot host-settings manifest
  23 suites passed, 0 skipped, 0 failed in 46s
node test/run.mjs settings-host settings-carrier catalogue-consistency host-metadata policy shells-presentation
  5 suites passed, 1 skipped, 0 failed in 7s
git diff --check 662a388..HEAD
  passed

The local catalogue suite skipped because this separate integration checkout had no native worker; it is not counted as a pass. The complete platform CI gates supply runtime coverage. Original red/green regressions, schema/prompt effects and bilingual changelog/docs are recorded in the individual PRs. All 19 selected heads were verified as ancestors, with other prerequisite heads inherited. The original user checkout is clean and untouched.

Environment

Local focused validation used Windows x64 and Node v24.19.0 with locked dependencies. Cross-platform evidence comes from the linked CI run. No model/provider request, live Desktop recovery or repository administration change is claimed.

ccch1mneyyy and others added 30 commits October 21, 2026 03:19
The 0.3.1 release notes headed the asset table "Target | SHA-256" and listed
the worker digest; 0.3.2 kept the same heading and listed the ZIP digest, so a
reader comparing an archive against the worker reports a false mismatch.

Record the contract instead of the numbers: the SHA256SUMS asset is
authoritative for the released tarballs, every tarball carries its native
worker digest in runtime/<target>/provenance.json, and the Release body
defines neither. Releases published from a maintainer machine have no run
summary and did not always carry SHA256SUMS, so their record is the in-package
receipt.

The troubleshooting guides gain the in-package checker, which needs no
platform-specific hashing tool, and docs/PROVENANCE.md records the historical
mismatch rather than editing a published Release.
PTC and discovery assembled the whole prompt once per tracked agent on
every reconcile, so creating one session paid for every session still
tracked. 38 bundles on Windows x64 grew 264/308/396/475/590/681/748/947
ms across eight session/create calls; with this change the same eight
rounds measure 195/226/270/260/295/329/358/373 ms.

Each agent now memoizes its presentation verdict against the tool names
it publishes and re-probes only when that set changes. reconcile() takes
the agents a change actually touches, and the publish-time snapshot reads
names instead of rebuilding a scope view per tool.

Refs #333, #359
Accept darwin-x64 in the runtime resolver and profile commands, declare it in every component target row, and add the macOS 15 Intel leg to CI and release.

macOS 12 lacks CLONE_ACL (xnu-8020); that older-kernel fallback is a separate follow-up. macOS 13+ shares the existing macOS path.
The installed-package check asserted darwin-x64 must be rejected, which fails on every host once the target is supported. Assert darwin-riscv64 instead; the matrix gate is unchanged.
The Intel leg measured 318 s, over the repo's >300 s line, so keep it out of validate-posix and ci-required. Add a separate continue-on-error job that runs the same gate and uploads native-darwin-x64.
Cover darwin-x64 in the macOS guide, usage, troubleshooting, roadmap, release, CI docs and changelog. Keep macOS 12's CLONE_ACL gap explicit as a separate follow-up.
The new validate-macos-intel step copied the node -e check without its closing brace, so Node exited with SyntaxError before the check ran. Restore the brace; the blocking legs were unaffected.
`reconcile` advanced `epoch` on every call, so the passes the new `targets`
argument turns into no-ops still invalidated every published `execute` guard and
every Native shadow. Those then answered POLICY_DENIED for a scope that was still
authoritative, which is why `discovery-composition` lost its combined Native/PTC
checks and `ptc` lost its presentation-change race.

A probe also recorded its surface on the entry before the republish that consumes
it ran. A pass a later reconcile superseded therefore left the next pass reading
that surface as already published, returning early forever; the PTC verdict never
took effect and `native-result` timed out waiting for the Native/PTC projections.

A separate `published` counter now moves only when a pass actually republishes.
`ptc`'s shadows and `discovery`'s guards compare it, because `discovery`'s probe
assembles the prompt and that reconciles other scopes. Probed surfaces stay
pending until the republish commits them.

Verified: `npm run typecheck`, `npm run verify` — 125 of 127 suites pass, the two
remaining are the local-only failures `bash-ipc` and `permissions`, which need the
pinned runtime receipts this checkout does not build and fail identically on
b963fb2.
…napshot

A departure passed an empty target set, which the pass normalized to "no restriction" and then probed every tracked agent on the one pass that has nothing to probe. An empty set is now a probe-free pass: it names nobody to probe while still asking for the republish a departure owes.

The per-publish snapshot now reads tool names through one src/surface.ts helper instead of an identical surfaceOf in each plugin, and both memo keys document that names are the whole key while the presentation verdict also reads the tools:ptc-only section text, so a flip without a name change costs one pass and never a permanent wrong surface.
`surfaceOf` asked `tools.schemas()` for the names it memoizes, and that
projector rebuilds one deep copy of every visible parameter schema per call.
Read the same visible map through `tools.view(scope)` instead, keeping
`schemas()` as a fallback for a runtime that exposes no view, and pair each
name with a `WeakMap` identity for the definition the view holds. A names-only
key returns a stale hit when a scoped registration shadows a global of the same
name, so missing the shadow publishes nothing on the change that owed a
republish. Identity costs one lookup against an object already in hand rather
than the `tools.get()` pairing that would rebuild the whole view per name.
visibleTools (the tooling:shell/file prompt section and the host-shell
denial gate) asked tools.schemas() and kept only the names, paying one
deep copy of every visible definition per assembly: 34.2 ms for 258
tools at the issue's own surface shape on the published 0.2.1-rc.2
runtime, against 0.043 ms through tools.view() (~800x). Cost tracks
nested schema nodes, not payload bytes (811 KB flat = 16.5 ms; 705 KB
nested = 34.2 ms), so the fixture is pinned to the issue's measurement.

visibleNames() reads view().keys() with schemas() as the fallback for a
host whose view is not reachable, so correctness outranks the cost there.

The discovery pre-step assembly is deliberately left alone: it is the
self-correction path for a presentation that flips without the names
moving, and memoizing it there breaks the ptc-sdk projections (#369).

Tests assert the two review gaps as well: a tools/change with no registry
movement reconciles from the discovery probe memo without assembling, and
the denial gate restricts without projecting schemas. Both fail when
reverted.

Stacked on #368: surface.ts and the view machinery come from there.
bench/cli.mjs spawns bench/run.mjs as a child and cannot inject a callback, so the runner's requirement of an injected io.seal made every interactive sweep exit 3 before spawning anything unless --no-seal was passed. Sealing is now opt-in with --seal, and every sweep - sealed or not - keeps each arm's results/ and summary.json, which bench report renders the report from.

--seal resolves bench/run/seal.mjs (an injected io.seal still wins), fingerprints both arms by hashing \dsh --profile <name> --dump-config\ into the arms[].profileHash that sealRun requires, and refuses before any session when a fingerprint cannot be read. sealSweep adapts the seal context's {base, cand} directory map to the directory list sealRun folds; that mismatch was invisible to the injected doubles and only a real sweep could expose it.
…mplate

Add bench/README-NEW.md (preparation, full and single-task sweeps, reports, every task and gate with the ops_* tools they exercise, and where temporary files land) and bench/README-mini.md (the short preparation path).

Rewrite bench/llm.patch.example.yml's header in English and add the credentials-local insert the working copy needs, since the base/headless bundles ship no credentials service.
DEFAULT_REPEAT drops 3 -> 1 and every task in bench/tasks/ declares
"repeat": 1, so an ab sweep without --repeat now runs each task once
per arm (12 sessions, 6 interleaved pairs) instead of twice per arm.
--repeat N still overrides everything; the default only covers a task
with no repeat field of its own. The default-value assertion in
test/bench-schedule.test.mjs follows so reverting the constant fails
the suite.
…weep report

The default group folder is now benchmark-YYYY-MM-DD-NN — the local calendar
date, numbered from -00, incrementing past anything already present — instead
of the ever-growing benchmark-test-NN. Allocation still happens exactly once
per sweep, still skips any same-named entry case-insensitively, and the clock
is injectable so suites assert exact names.

A finished sweep now renders its own verdict through compare.mjs's
renderReport and writes "DSH-OPS Benchmark Report <UTC>.md" into the group
folder (or the --out directory) — the bench report artifact without a second
command, re-renderable at any time. --no-report skips it; an interrupted
sweep writes none, because a partial run is not a comparison; a failed write
is a loud note, not a failed sweep. The ab help text and the three bench
READMEs follow, along with the repeat-2-to-1 leftovers in README-NEW's task
table.

api-rename's corpus shrinks to one fifth: symbolTree files 60 -> 12 (seed
unchanged, all five module shapes present, the look-alike-only decoys
included), so the model searches, reads and edits 11 touched files instead
of 51. The task's title and the README-NEW row follow.
Durations were already recorded per session; compare-core now aggregates
them like steps — durationMsMedian / durationMsMin under the same
--aggregate median|min, per-task delta.durationPct, and totals summed over
the task medians. The per-task pairs table gains a
"time base→cand (Δ%)" column (seconds, one decimal, — when unmeasured),
and its Δ% is painted like every other percent.

The bench docs' "never judge time" principle statements are gone, and the
report footer now says time is reported like any other metric. The gate
itself is unchanged: it judges pass rate and paired tokens, and duration
stays out of every verdict — the new core assertions pin that gate
outcomes do not move with duration.
README-NEW.md and README-mini.md are gone: bench/README.md now carries the
short preparation-and-usage guide on its own. No script, manifest or doc
referenced the two removed files.
…air-loop

The generated report's heading is now "# DSH-OPS Benchmark Report (beta)";
the file name keeps its old shape ("DSH-OPS Benchmark Report <UTC>.md"),
which the report subcommand, the runner help and the bench README all say.

Every rendered "cand" label becomes "ops" — the first table, the (ops only)
marker, the tool table, the three diagnostic headers and the Evidence line —
matching the bench-ops arm label. JSON keys, CLI flags and warning codes are
unchanged: they are the machine contract.

gate-repair-loop's pipeline is 12 stages instead of 24; every stage is still
broken, so the repair loop halves with it. Seed, probes and linesPerGate are
untouched, and the fixture regenerates with all invariants intact.

test/bench-cli drops the README ↔ run.schema.json cross-check — the bench
docs are now one short README — and keeps the schema self-checks.
The report gains "Per-request overhead (what every request costs before any
work)": one first-request cell per task (base → ops with the absolute delta
and a painted Δ%). Real sweeps never recorded the data it needs, so the
session fold now derives metrics.prompt exactly as the aggregator defines
it — per-step prompt = input + cacheRead + cacheWrite, the first request set
only by step 1, per-turn firsts, reported all-or-nothing — and new sweeps
light the table up while archives without the data render the section's
Skipped note instead of inventing numbers.

Everything else got smaller: Warnings, Conclusion, Evidence, the steps and
tool calls table, the usage split table and the closing footer are gone, so
the report is four data tables and nothing else. The gate's verdict still
travels through the exit code and the comparison document, unchanged.
Section headings lose their parenthetical qualifiers (Tool calls, Per-task
bucket detail), per-column headers read "steps: base→ops (Δ%)" to separate
the metric from the direction, and renderReport drops its sources parameter,
which only the removed Evidence ever used.
bench/README.md gains a task table: fixture size, what each task measures
(symbol rename vs decoys, paged reads against stale-comment bait, layered
config priorities, shell-side aggregation, the run-fix-rerun repair loop,
exact log extraction) and which ops_* tool each step maps to. The numbers
match the current fixtures — api-rename 12 modules and gate-repair-loop 12
stages included — and the expectations are the generators', recomputed per
run.
The bench README becomes the Benchmark Manual: setup says what it prepares
(the two headless profiles and the locally built plugin), the LLM overlay
section is reworded, and the group-folder naming plus the auto-written
report move into their own "结果在哪看" section.
…chmark-switches-296

# Conflicts:
#	docs/CHANGELOG.md
@T-Auto

T-Auto commented Oct 25, 2026

Copy link
Copy Markdown
Owner

已按分片落地(2026-10-25)

21 个分片已按 #407 的顺序全部合入 main(最终 main = dfafddc941695090df2c6e2e323193785aec4eb6,落地明细见 #407 评论)。

按 #407 第 2 节对本集成草稿的重新评估:

  • 本 head 2e261035f88780015a7e132d36e7614e6cf4a8de 与落地后 main 的树差异仅 docs/CHANGELOG.md 的条目顺序;两边非空行集合完全相同(1111 行,集合差异 0),没有任何代码/文档内容差异。
  • 因此本草稿不包含仍需单独合并的实现内容,作为聚合落地入口的使命已完成。
  • 原 PR 事件 CI(40116812179)与 dispatch 组合验证(40115118596)均绿;落地后 main 的完整 12-job 验证为 40164321217。

关闭本 Draft。分片 PR 各自的合并状态与 issue 收口见 #407。

@T-Auto T-Auto closed this Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants