Skip to content

feat(plugins): migrate F202 Train C1 package runtimes - #54

Draft
mindfn wants to merge 219 commits into
zts212653:mainfrom
mindfn:feat/f202-train-c1-plugins-migration
Draft

mindfn wants to merge 219 commits into
zts212653:mainfrom
mindfn:feat/f202-train-c1-plugins-migration

Conversation

@mindfn

@mindfn mindfn commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Start here — current status (2026-09-30)

Draft on purpose. Do not merge or publish yet. This PR and Host PR #1487 still merge together, after the remaining package/Host work and Landy's hands-on acceptance. Local approvals are quality evidence, not upstream approval or merge authority.

  • Live HEAD: 847176ecae821800f24d11acac19540df3665033 (p2c pushed for exact-head CI and local Sol review).
  • Latest fully approved checkpoint: 6fa5c46e0ec1fe53f8a52ea19f8010cc35ac1df7.
  • Current release line: @clowder-ai/plugin-contract@0.1.0-beta.27, @clowder-ai/plugin-sdk@0.2.0-beta.11, @clowder-ai/companion@0.1.0-alpha.18. These prereleases are not being published by this draft PR.
  • Maintainer review request: the nine finished slices through 6fa5c46, with commit/range, size, tests, CI, local approvals and attested artifact digests, are itemized in this comment. p2c is deliberately excluded until its local exact-head review closes.
  • Truth source: the Host branch ledger, docs/plans/2026-09-21-f202-c1-contract.md, owns per-slice specifications, review verdicts and artifact identities. This repo's aggregate migration plan owns the package-side inventory and terminal acceptance.

Completed before the detailed e2aef8f checkpoint

Wave State and local approval
Contract/SDK + A2 carrier foundation Done and cross-individually reviewed: contract/SDK plus all seven connectors on the common message-subscription / context.messaging.* / { params, invocation } shape. Review anchors are in the plan and Host ledger.
W1 5/5 done on both sides: video-generation, video-analysis, weixin-mp, enterprise-workflow and wechat-visible-reader. Each package/Host consumption slice received local cross-individual approval; Host copies were removed. See the W1 ledger.
W2 connectors W2-1, W2-2 and the connector consumption/lifecycle wave are done and locally reviewed: QR login and credential validation, rich blocks and typed media, send/receive, lifecycle receipts, display names, durable pending-effect/tombstone handling, multi-binding delivery isolation and Telegram correlation/cleanup. Artifact batches 1–5 were independently checked and accepted by the Host. See the W2 ledger.

Locally approved slices since e2aef8f

Slice Approved checkpoint
W2-3 p1: package the Host extension/native host Opus approved 678681a; exact-head CI green
Upstream #60–#62 sync / companion alpha.9 Opus approved 1ba2423; exact-head CI green
Contract beta.24 / SDK beta.7 h1/h2/h3 freeze Opus approved 29d82fe; Fable verified canonical bytes
Contract beta.25 / SDK beta.8 main #63 sync + escape audit Opus approved 55862d3; audit continuity closed at 736256a; exact-head CI green
SDK beta.9 real module-carrier data-directory repair Sol approved 6c02298; Astra verified canonical bytes
W2-3 p2a module-plugin skeleton and real entrypoint Sol approved aef8d6a; exact-head CI green
R3 sync #1: contract beta.26 / SDK beta.10 / companion alpha.16 + immutable-attestation guard Sol approved the sync, Astra verified the closure at a17b998; the later Sol range explicitly includes it
W2-3 p2b real v2 append/list/ack socket client Sol approved afeaa70; exact-head CI green
Sync #2: contract beta.27 / SDK beta.11 / companion alpha.18 Sol approved 6fa5c46; Astra verified canonical bytes; exact-head CI green

Current dependency chain

  1. p2c (68f15b6 16287c4 847176e) is in local exact-head review: lazy 2s→60s list backoff, honest helper status including invalid installation, transition-only logging and the final catalog pin.
  2. p2d follows: stable extension load path, update/reload plus tested rollback, helper-update policy, package-owned extension assertions and icon hashes. p2d carries Host h3c-3's acceptance evidence.
  3. Batch 6: seven connector artifacts plus personal-chrome-companion, independently rebuilt and verified.
  4. Host h3c-3: switch ChatGPT Pro to the installed package and remove the Host copy. Host h3c-1 and h3c-2 are already approved.
  5. Hands-on acceptance: real-account QR login and IM send/receive, plus the remaining real-device checks.

W3 (GitHub cluster), W4 (collective + GenOffice docx) and the Feishu minutes sync have not started. W2-4 (delete connector-specific Host framework/pages) follows the real-account connector run.


The text below is preserved from the original aggregate description. Its checkpoint/evidence numbers predate the 2026-09-30 status above.

What

Completes the Plugins half of the F202 Train C1 two-PR cutover as one aggregate migration.

  • Freezes the code-derived 11-row migration inventory and classifies all 20 repository package directories.
  • Adds the carrier-neutral SDK module/lifecycle/action boundary and deterministic default-export discovery.
  • Migrates all seven IM connectors to complete Host-loadable package modules with idempotent lifecycle cleanup.
  • Adds exact catalog, publish-order, packed-entrypoint, and blank-consumer admission evidence for those seven connectors.
  • Keeps Host authority over grants, connector bindings, wake policy, config/secrets, durable state, lifecycle, and delivery settlement.

C1 terminal acceptance

The durable finish line is in docs/plans/2026-09-19-train-c1-plugins-aggregate-migration.md and migration/f202-train-c1-inventory.json.

PR #54 closes repository-wide contract/SDK/YAML/runtime/catalog/pack/fresh-consumer compatibility, not only the new package directories. Every Manager-installable package has one canonical manifest truth, an explicit runtime/lifecycle disposition, honest package contents, catalog status, and a fresh-consumer path.

Core PR #1487 consumes exact reviewed artifacts through one carrier-neutral lifecycle/action boundary, proves no-double-run and recovery, switches defaults, and deletes legacy execution paths without package-specific runtime branches. The dependency order is Plugins exact Linux pack → Core integration journey → Plugins merge/automatic publication → Core registry pin/final journey/merge. There is no third C1 cleanup PR.

Historical checkpoint from the original description

Exact HEAD 9e285ecdb53627250a6bca5894f5c68556ed4746:

  • @clowder-ai/plugin-sdk@0.1.0-beta.12 exports PluginModuleEntrypoint, definePluginModule, activateDefinedFeature, and ActivePluginFeature; builtin entrypoints default-export the validated module shape.
  • Telegram, DingTalk, Feishu, WeCom Agent, WeCom Bot, Weixin, and XiaoYi export real dist/plugin-entrypoint.js modules and retain provider-specific egress behavior behind the common Host lifecycle/action boundary.
  • Their packed READMEs describe the completed Host-loadable builtin runtimes; catalog admission rejects the withdrawn standalone/pending-runtime wording.
  • All seven connector artifacts are in catalog truth and the dependency-ordered automatic publish workflow; their exact Node 24.18.0 / npm 11.16.0 pack coordinates are checked by catalog CI.
  • Fresh-consumer evidence installs every packed connector plus the packed SDK/contract, validates the packed manifest, imports the declared builtin entrypoint, enforces the default-export contract, creates the plugin, and checks activated feature IDs.
  • GitHub Operations is the sole remaining aggregate RED: its package module needs the generic Host-owned scheduled-action/event-publication composition already being coordinated with Core #1487. No GitHub-specific Host port or package-local authority is accepted.

Evidence

  • Plugin contract: 378/378 pass.
  • Seven connector package suites: 65/65 pass; package typechecks/builds pass.
  • Exact-toolchain catalog check: pass.
  • Packed fresh-consumer connector journey: 1/1 pass.
  • Release configuration/conservation tests: 28/28 pass.
  • Inventory: 7/8 pass; sole expected failure is official.github-operations is missing from catalog.
  • git diff --check: clean.

Boundaries

  • Draft only; no merge or publication authority is inferred.
  • No package-local persistence, ambient Host authority, raw provider-id-as-handle substitution, provider-specific Host wire, or manual npm publication.
  • StackChan physical hardware and new managed/front-end surfaces remain Train C2; wechat-visible-reader/weixin-mp agent-side limb/skill consumption remains C1.
  • The published video-generation ambient-authority issue remains independent P1 task 0001789870442375-002134-eaaa5365.

[砚砚/gpt-5.6-sol🐾]

@mindfn mindfn changed the title feat(plugins): stage F202 Train C1 aggregate migration feat(plugins): migrate F202 Train C1 package runtimes Sep 20, 2026
@mindfn
mindfn force-pushed the feat/f202-train-c1-plugins-migration branch 2 times, most recently from 4d3174d to dc53404 Compare September 20, 2026 16:54
Why: Train C1 needs package-owned business implementations and connector adapters before Core can perform a no-double-run cutover. Freeze the eleven-item inventory, add the public SDK session surface, migrate three business plugins and five provider adapters, and keep unresolved Host binding/checkpoint activation fail-closed outside the catalog.

Verification: connector package typecheck and 30/30 tests pass; SDK 313/313 passed before checkpoint; fresh-consumer covered the three cataloged business packages; packed runtime entrypoint guard 3/3 passes; inventory remains intentionally RED at the first uncataloged connector.

[砚砚/gpt-5.6-sol🐾]
Why: the aggregate migration needs package-owned Feishu, Weixin, and GitHub operation surfaces without freezing unapproved Host binding or checkpoint APIs. Explicit configuration and Host ports preserve authority while catalog and publication remain fail-closed until Core composition is approved.

Also closes the existing WeChat visible-reader release workflow omission and updates the publication conformance count to the nine currently cataloged public packages.

Verification: pnpm -r --workspace-concurrency=1 typecheck; pnpm -r --workspace-concurrency=1 test; connector manifests validated through the built contract; exact-toolchain dry-run packs include README, manifest, shrinkwrap, icon, and dist.

[砚砚/gpt-5.6-sol🐾]
Why: the C1 checkpoint exposed two semantic gaps: publication coverage was pinned to duplicated literals instead of catalog truth, and the GitHub Operations package shell was described like a runnable adapter despite depending on unapproved Host D/E authority. Derive the release invariant from catalog provenance, make the blocked port status machine-readable, and record the already-wired packed-entrypoint gate without advancing catalog or publication.

[砚砚/gpt-5.6-sol🐾]
Why: protected Linux CI and two exact local Node 24.18.0/npm 11.16.0 packs agree on the final video-generation bytes, while the catalog still recorded an earlier pre-final-build candidate. Refresh only the immutable SHA-1/SHA-512 coordinates so the existing fail-closed catalog check proves the actual reviewed source.

[砚砚/gpt-5.6-sol🐾]
Why: Train C1 was incorrectly reframed as waiting on a new D/E public contract even though the contract and SDK surfaces were already closed. Restore the agreed split: Plugins completes package code while Core maps existing Host authority, cuts over, and deletes legacy implementations.

[砚砚/gpt-5.6-sol🐾]
Why: Core can delete provider-specific connector wrappers only after the packages own explicit provider lifecycle and ingress normalization while Host binding, wake, retry, and settlement authority stay outside package code.

[砚砚/gpt-5.6-sol🐾]
Why: Host disable can arrive while a provider start is still connecting. Waiting for that transition before provider shutdown prevents a late live stream from surviving drain, while a shared async idempotent lifecycle lets Core map both connectors without provider branches.

[砚砚/gpt-5.6-sol🐾]
Why: standalone connector manifests declare provider ingress methods, but the closed stdio registry cannot execute them and the handshake exposes no Host-issued binding handle. Preserve the exact fail-closed evidence before choosing an authority-safe composition path.

[砚砚/gpt-5.6-sol🐾]
Why: events.publish is already a valid authority-safe provider ingress, but the closed Host delivery shape still cannot carry a Host-resolved provider coordinate and manifest outbound methods are not executable wire rows. Keep the reproduction precise so implementation can continue on every satisfiable half.

[砚砚/gpt-5.6-sol🐾]
Why: Train C1 must finish as one repository-wide package compatibility pass, with packages as distribution units and runtime carriers hidden behind one Host lifecycle/action boundary. Freeze that terminal contract, classify every package directory, and checkpoint the reviewed SDK module seam plus Telegram/DingTalk consumers without inventing a provider-specific wire.

Verification: plugin-sdk 325/325; Telegram 10/10; DingTalk 11/11; all three typechecks pass; repository inventory 7/8 with the sole intentional catalog RED for official.connector.dingtalk.

[砚砚/gpt-5.6-sol🐾]
Why: the pause gate requires the executable Plugins ledger to record the exact Core counterpart that was actually read and to disambiguate retained physical-hardware limb work from C1 agent-side limb/skill consumers.

Verification: inventory contract/provenance checks pass; the suite remains intentionally 7/8 with only official.connector.dingtalk missing from catalog.

[砚砚/gpt-5.6-sol🐾]
Why: the C1 cutover requires every connector package to expose the same Host-loadable module lifecycle, preserve Host-owned binding and state authority, and ship a deterministic packed entrypoint instead of a dangling stdio declaration.

Also pins the builtin default-export discovery guard and registry-canonical production shrinkwraps so catalog and fresh-consumer admission can fail closed.

[砚砚/gpt-5.6-sol🐾]
Why: the migrated connector runtimes need deterministic catalog coordinates, dependency-ordered publication, and a fresh-consumer proof that imports each manifest-selected module default through the SDK guard. This closes all seven connector artifacts while leaving GitHub Operations as the sole explicit aggregate RED.

[砚砚/gpt-5.6-sol🐾]
Why: the aggregate connector publish gate adds two multiline shell blocks, so the workflow syntax regression must count and parse all seven instead of failing on its stale five-block inventory.

[砚砚/gpt-5.6-sol🐾]
Why: all seven connector modules are now cataloged and fresh-consumer installable, but their packed READMEs still claimed standalone runtime implementation remained pending. Describe the completed Host-loadable builtin modules, refresh the unpublished candidate coordinates with the pinned toolchain, and make catalog admission reject stale runtime status.

[砚砚/gpt-5.6-sol🐾]
Why:
- B8: remove ambient node:child_process/ffmpeg authority from connector-feishu
  (no process/filesystem capability in the contract vocabulary); non-opus audio
  is now delivered as msg_type:file under its original name, source-guard test
  pins the absence of the ambient path.
- N1/N3: feishu handleWebhook returns {kind:'skipped',reason:'not_running'}
  when not running instead of silently dropping and reporting 'processed';
  running-phase routeCard false maps only to chat_type_unknown.
- N2+B5 residual: dingtalk client.connect and feishu client.start are bounded
  by a 30s timeout; stop-during-connect swallows the stale-generation path so
  stop() cannot surface an unhandled rejection.
- B3 residual: wecom-bot stopStream detaches SDK listeners via removeAllListeners.
- B7: pnpm test:train-c1-inventory is now wired into contract-ci validate job,
  making clause 3 repository-wide compatibility closure executable evidence.
  The github-operations catalog exemption is pinned exactly to
  implementationStatus 'port-declared, implementation-pending-in-plugins' with
  deepEqual ['github'] so it tightens automatically when the status flips.
- catalog shasum/integrity tuples for all 7 connectors regenerated with the
  pinned pack toolchain (Node 24.18.0 / npm 11.16.0) since package bytes changed.

Evidence: pnpm test 212/212 across 10 packages, catalog:check ok,
test:fresh-consumer 1/1, test:train-c1-inventory 8/8, conformance 34/34 + 18/18,
typecheck clean, git diff --check clean.

Co-authored-by: sol's uncommitted work reviewed and landed in this commit.

[小狸/k3🐾]
…nsent-surface gate

Why:
- F1: the production outbound path always carries `url:` (never absPath);
  downloadToTempFile mapped every non-image Content-Type to `.jpg`, so even
  true OPUS audio degraded into a `.jpg` file card once the ffmpeg sniffing
  was removed. Extension now comes from Content-Type (audio/opus keeps
  `.opus`), with URL-path fallback and a derived display name, and the url:
  branch is covered by a test.
- F2: lark WSClient.close() only terminates the socket registered after
  'open'; a stop() landing pre-open left an authenticated, self-reconnecting
  socket nobody could kill. PausableLarkWsClient terminates the current
  socket, installs a birth guard that kills any socket the SDK opens after
  stop, and no-ops pingLoop so a late 'open' cannot restart the ping timer.
  autoReconnect is disabled deliberately: SDK-owned reconnection was the
  revival mechanism; reconnect supervision belongs to the Host lifecycle.
- F3: lark WSClient.start() and DWClient.connect() both resolve before any
  connection exists, so startStream/start settled early and the runtime
  reported 'running' over a dead connection. start now waits until the SDK
  registers an open socket (feishu: wsConfig.getWSInstance(); dingtalk:
  client.connected), bounded by the existing 30s timeout, and aborts
  cleanly when stop() races.
- F4: packaged READMEs are the install consent surface but under-reported
  capabilities (7/7 drift). READMEs now disclose the exact plugin.yaml
  capability set, and a new inventory gate fails if any packaged README
  omits a declared capability.
- Also: TOCTOU state recheck after the name-resolution await in routeEvent/
  routeCard; overclaim comment corrected; dead uploadToFeishuInner collapsed;
  catalog shasum/integrity tuples regenerated for the 9 packages whose
  bytes changed (pinned toolchain Node 24.18.0 / npm 11.16.0).

Evidence: pnpm test 1083/1083 across the repo, catalog:check ok,
test:fresh-consumer 1/1, test:train-c1-inventory 9/9, conformance 34/34 +
18/18, typecheck clean, git diff --check clean.

Co-authored-by: 缅因猫 sol (cat-eqdvbcxw) <sol@cat-cafe.local>

[小狸/k3🐾]
…regen

Why:
- G1: both connectors reported `running` over a dead ingress. Feishu now
  treats the socket's own 'close' as the liveness truth (lark leaves a dead
  socket registered with autoReconnect off): unexpected close drops the
  runtime out of 'running' and drives a supervised backoff reconnect, the
  same acceptReconnects pattern WeComBotAdapter already owns. Dingtalk gets
  a stream watchdog polling the client's connected+registered truth and
  drains + restarts dead streams. The watchdog is armed only on transitions
  into 'running'; arming at the top of start() leaked the interval for the
  process lifetime whenever startStream rejected (found via test hang).
- G2: static servers serve OPUS voice data as audio/ogg (the ogg
  container); the MIME map now keeps it on the .opus path instead of
  degrading into a .ogg file card, and a display name without an extension
  gets .opus appended so file_type/file_name stay consistent.
- G3: the webhook TOCTOU fix reported {kind:'processed'} with delivered=0.
  routeEvent/routeCard now return the real delivery outcome and the
  webhook derives 'processed' strictly from it; a guard-killed route
  reports skipped/not_running.
- G4: the consent-surface gate read the first feature block of
  disposition==='migrate' packages with a hand-rolled YAML scan. It now
  parses plugin.yaml with a real parser (fail-closed), covers every
  Manager-installable package (managerInstallable, not disposition), and
  unions capabilities across ALL features; companion gains a README
  consent surface. A mutation test that added a second-feature capability
  and a companion capability previously passed silently.
- G5: downloadToTempFile used tmpdir()/...-${Date.now()}, so two concurrent
  sendMedia calls in the same millisecond wrote each other's bytes and both
  reported success. Each download now gets a private mkdtemp directory.
- N2/N5: dingtalk startStream shares one deadline between the connect()
  race and the connected+registered liveness poll (was 2x30s), rejects when
  the SDK gives up, and is covered by tests.
- Catalog: connector-feishu, connector-dingtalk, companion artifact
  shasum/integrity regenerated with the pinned Node 24.18.0 + npm 11.16.0
  toolchain after rebuilding dist; pnpm catalog:check passes end-to-end.

[小狸/k3🐾]
…backoff, mechanical class scans, catalog regen

Why:
- H1: feishu start() accepted any registered socket as connected; the lark SDK
  leaves a CLOSING/CLOSED socket registered when autoReconnect is off, so a
  flash-close resolved start() as "running" with a dead socket and no recovery
  (permanent death on the second reconnect). Registration is not liveness: the
  poll loop now accepts only readyState === OPEN (the SDK's own isOpen truth)
  and throws otherwise, routing the failure into the supervised reconnect.
  The synchronous CLOSING/CLOSED branch in watchSocketClose is gone — the
  accept loop guarantees OPEN in the same tick, and the sync branch fired while
  state was still 'starting', where the hook signal was dropped. Fakes carry
  readyState like a real ws socket.
- H2: the audio/ogg MIME special-case declared real Vorbis/Speex ogg as opus.
  Opus is now derived from bytes (OggS magic + OpusHead at offset 28), not from
  the MIME header; a non-opus ogg degrades back to the file card it produced
  before. Bidirectional tests pin both directions (revert = red).
- H3: inferFeishuFileType still did a bare index into FEISHU_EXT_TO_FILE_TYPE,
  so 'constructor'/'__proto__' URL segments mapped to prototype values
  (file_type "function Object()..."). Object.hasOwn + unit tests.
- H4: genoffice-docx was the only managerInstallable package with no README;
  the gate's capabilities.length===0 early-continue skipped even the README
  existence check. Added the README (zero-capability disclosure page) and the
  gate now requires an install page for every installable package regardless
  of capability count.
- Backoff: reconnect delay was a constant; commit messages said backoff while
  the code retried ~700x/hour, each hammering a fresh tenant_access_token.
  Both connectors now double from a base (default 5s) to a cap (default 60s)
  with ±20% jitter, and reset on every transition into 'running'.
- Mechanical class scans (audit scope derived from commands, not memory):
  * prototype-chain reads on Record maps: weixin-mp EXTENSION_MIME_MAP (bare
    [ext] after slicing the dot — same H3 shape) and video-generation
    'ext in MEDIA_MIME' (in walks the prototype chain) both fixed with
    Object.hasOwn; plugin-contract CAPABILITY_TABLE is safe (keys iterated
    from Object.keys); feishu's two maps were already guarded this round.
  * tmpdir() + non-random names: weixin convertWavToSilk used
    tmpdir()+Date.now().silk — the G5 twin in a live connector; now mkdtemp
    private dir + recursive cleanup in sendMedia's finally. weixin :1001
    (randomUUID) is the control; weixin-mp handlers:38 combines
    Date.now()+hrtime.bigint()+seq (effectively unique, justified);
    wechat-visible-reader cache files are content-addressed by source digest
    (justified).
  * existence-as-liveness: the only !== null liveness gate left is feishu's
    registration gate, which now derives liveness from readyState === OPEN;
    dingtalk's isStreamLive gates on the SDK's connected && registered truth;
    xiaoyi checks readyState === OPEN everywhere.
- Catalog: regenerated artifact hashes for the six repacked packages. The
  companion entry was additionally corrected: its recorded hash did not
  reproduce from committed sources even on a pristine de3a93c checkout
  (pre-existing round-4 drift, verified by stashing all round-5 changes and
  re-running the check); the entry now carries the deterministic pack bytes.
  pnpm catalog:check EXIT=0; pnpm test 1103/1103.

[小狸/k3🐾]
Why: round 5's five blockers share one root cause — the acceptance evidence
source (wrong remote pushed, local env treated as authority, no pre-merge
gate sees publishability). Fixes plus two gates that see the class, not the
instance.

- B1: round-5 commit was pushed to origin (upstream) instead of the PR's
  head repo (fork); the PR never moved. This round pushes to the fork.
- B2: revert companion catalog shasum/integrity to the recorded values —
  CI's pinned toolchain reproduces the recorded bytes; my round-5 regen had
  diverged locally, the record was truth.
- B3: startIngress() now force-closes a ws client whose start() throws
  (H1 made that the routine path; the leak was the F2 orphan reborn) and
  handleUnexpectedClose() checks caller identity — an orphaned client's
  late close can no longer tear down the healthy current connection.
- B4: genoffice-docx README.md enters package.json files[] and both
  assert-pack-ready allowlists; the undeclared entry would have failed
  prepack only in the post-merge publish job (pack-publish-artifact uses
  --ignore-scripts, and CI's publish job is push-to-main only).
- B5: prototype-chain lookups hardened at companion/src/errors.mjs and
  feishu-card-formatter.ts (hasOwn; ?? and || pass truthy prototype hits);
  wechat-visible-reader compiles in a per-process mkdtemp staging dir and
  atomically renames into the shared digest-keyed path (concurrent swiftc
  writers can no longer leave a half-linked binary that access(X_OK)
  approves and we execute). weixin-mp handlers.ts:38 needs no change:
  Date.now()+process.hrtime.bigint()+monotonic counter is unique per
  process even under same-ms bursts; collision needs cross-process ms
  equality AND counter reset, and the payload is a non-sensitive session
  transcript, not a shared build artifact.
- Gate 1: scripts/pack-gate.mjs packs every publishable package WITH
  lifecycle scripts (prepack) on the PR; catalog:check structurally cannot
  see this class. Root script pack:gate; CI step after Machine catalog.
  Build order in pack:gate is explicit and sequential — pnpm -r build
  races plugin-sdk against companion and loses.
- Gate 2: scripts/assert-pr-head.mjs asserts the sha under test equals the
  PR's live head via the GitHub API; CI runs it first on pull_request.
  Kills the stale-green class that let a wrong-remote push stand.
- CI push path table gains stackchan/** and the two new scripts.
- Catalog regen for the four byte-changed packages (feishu, companion,
  wechat-visible-reader, genoffice-docx); catalog verified against the
  pinned toolchain.

Verification: full pnpm test 1105/1105 fail=0 (35 feishu runtime tests
including two new B3 cases); pnpm catalog:check EXIT=0; pnpm pack:gate
19/19 publishable packages pack clean with prepack; fresh-consumer green.

[小狸/k3🐾]
Why:
- C2: weixin-mp convert_markdown derived its output path from
  Date.now()+hrtime+module counter — opus measured 35.67% consecutive
  hrtime collisions and per-worker counters restarting at 0, so concurrent
  conversions could overwrite each other's article HTML. Now each
  conversion gets a private mkdtemp(0700) directory; test pins distinct
  output paths per conversion.
- A4 residue: wechat-visible-reader native runner no longer branches on
  execute === defaultExecutor — staging compile is unconditional, so an
  injected execute seam covers the same path production takes (the old
  gate made the only compile test unable to reach the staging branch).
  Default cache moved from bare tmpdir() to a private
  cat-cafe-wechat-reader-cache dir created 0700. Compile test now writes
  the -o target and asserts the staged path != final executable.
- C1: pack gate deterministically fails on feishu-meeting-intake (rerun
  of CI run 35522543157 reproduced the npm-internal "Exit handler never
  called!" exit 1). It is the only bundledDependencies package; the real
  publish path packs with --ignore-scripts and never runs its prepack,
  so the gate cannot make that release safer. Explicit, commented
  exemption instead of a silent skip.
- Gate honesty follow-ups from opus: pack-gate step renamed (18/19
  prepacks are just pnpm build), validate job gets permissions block
  (contents+pull-requests read; gh api 403s on private repos otherwise),
  CI asserts git rev-parse HEAD == PR head before the script,
  assert-pr-head comment narrowed to what it can actually catch (a
  wrong-remote push produces no run; the delivery ritual in CONTRIBUTING
  is the local half), pack-gate uses fileURLToPath and a 16MB maxBuffer.

Verified: weixin-mp/wechat-visible-reader test+typecheck green; pack gate
18 ok + 1 explicit exempt; full pnpm test 1105/1105; catalog regen for
the two source-changed packages, catalog:check EXIT=0.

[小狸/k3🐾]
Why:
- Rebasing onto main (7251983, PR zts212653#55) conflicted on plugin-sdk version
  pins and the fresh-consumer assertions; main is ahead
  (sdk 0.1.0-beta.13, contract 0.1.0-beta.17) so the branch takes main's
  higher versions instead of its own older bumps (beta.12/beta.16).
- catalog.json companion block regenerated during the rebase picked up the
  stale alpha.2 artifact; restored main's alpha.3 artifact metadata
  (integrity/shasum) since packages/companion is alpha.3 on main.
- pnpm-lock.yaml already matched main's versions after auto-merge; no
  lockfile change needed.

小狸 [狸花猫/k3🐾]
Why:
- The rebase onto main (7251983) changed package contents (companion
  README merge + errors.mjs hardening, version-pin reconciliation),
  so every packed tarball hash drifted from the catalog entries that
  round 6 regenerated pre-rebase. catalog:check packs each plugin via
  scripts/pack-publish-artifact.mjs and asserts integrity/shasum; all
  13 entries are refreshed from actual packs. No versions changed.

小狸 [狸花猫/k3🐾]
Why:
- After the version reconciliation with main (785626d), plugin-sdk is
  0.1.0-beta.13 but the seven connector packages still pinned
  0.1.0-beta.12, which no longer resolves on the npm registry
  (fresh-consumer install failed with ETARGET). The pins move to
  beta.13; pnpm-lock and catalog artifact hashes regenerate
  accordingly (packing verified deterministic across repeated packs).

小狸 [狸花猫/k3🐾]
Why:
- video-analysis/video-generation dist had been built against the stale
  pre-rebase plugin-sdk d.ts, so their packed hashes drifted again after
  the full rebuild. Re-verified determinism: repeated clean rebuilds
  produce identical dist and identical tarballs. The flip source was
  the stale SDK d.ts, not the pack pipeline.

小狸 [狸花猫/k3🐾]
Why: npm registry no longer carries plugin-sdk beta.12 (replaced by beta.13
when PR zts212653#55 bumped plugin-sdk on main), so connector shrinkwraps must pin
beta.13 or fresh-consumer install fails with ETARGET. npmmirror-based
regeneration rewrote resolved URLs off registry.npmjs.org and violated the
catalog resolved-URL conformance rule, so instead restore the original
shrinkwrap trees and patch only the plugin-sdk/plugin-contract entries with
registry.npmjs.org metadata pulled from the live registry.

小狸 [狸花猫/k3🐾]
Why: macOS cleaned the pinned Node/npm installation under /tmp during the train, leaving later artifact checks incomplete or silently using the system npm. Document a persistent install path and make /tmp-only toolchains explicitly unsupported.

[砚砚/gpt-5.6-sol🐾]
…onnection status

Why: each Host poll currently opens another socket while the helper is absent, and authorization status hides the helper state. Observe actual socket connections independently of business results, gate only list with lazy 2s-to-60s backoff, show last-known reachability in the rendered status label, and log only state transitions. Preserve explicit probes and dispose pending exchanges without retry timers.

Evidence: new real-socket reachability checks fail on afeaa70; targeted p2b/p2c/carrier tests 41/41, visible status and lifecycle checks 13/13, package typecheck passed. Full package suite and final post-sync catalog/gate remain pending; no remote push.

[astra/gpt-6-astra🐾]
Why: rejected pairing records must replace stale reachability in owner-visible status, with repair guidance and transition-only logging, without activating reconnect backoff.

[缅因猫/astra/gpt-6-astra🐾]
Why: the p2c runtime and repair guidance change packed bytes; compute the catalog identity after rebasing onto the attested beta.27 and beta.11 dependency closure.

[缅因猫/astra/gpt-6-astra🐾]
@mindfn

mindfn commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

Incremental maintainer review request — completed #54 slices through 6fa5c46

Following the maintainer's slice-review guidance on #1487, this separates the completed, locally approved work from the unfinished aggregate.

There has not yet been an upstream maintainer review or review comment on #54. The last maintainer-visible checkpoint is the PR opening status dated 2026-09-25, which records 63b551a and says p1 was still under review. The nine completed slices below are ready for scoped review.

Everything before e2aef8f—the contract/SDK and seven-connector A2 foundation, W1's five packages, the W2 connector work through contract beta.23, and artifact batches 1–5—is also finished and locally approved. The refreshed PR opening status summarizes those earlier slices with Host-ledger anchors; we can itemize them in the same format on request.

The reviewed checkpoint is exact commit 6fa5c46e0ec1fe53f8a52ea19f8010cc35ac1df7. At draft time the live PR has advanced to 847176ecae821800f24d11acac19540df3665033, because p2c has been pushed for CI and local review. Please exclude 6fa5c46..847176e from this request: p2c is listed under “in progress” below and is not yet being presented as ready.

1. Ready for your review

The commit lists are authoritative. Later slices build on earlier ones; p2a and p2b are logical commit sets because version-sync commits landed between their implementation rounds. Their size figures therefore should not be added to the contiguous version-sync ranges.

# Slice Commits / range Scope and size Local approval
1 W2-3 p1: move the Host's Personal Chrome extension and native host into personal-chrome-companion fcc594d d350937 63b551a fd79279 7a9087e 678681a (e2aef8f..678681a) 46 files, +8,392 −846; package extension/native-host, their real tests and fresh-consumer coverage Opus approved exact 678681aef1ca1c7bccd4c2c662b68d35833274a7 (local review …000180)
2 Upstream sync through #60–#62 and companion collision-safe bump merge d25c4eb, then 1ba2423 (678681a..1ba2423) 2 first-parent commits; 38 files, +639 −36; companion source/tests/assets, catalog and ledger Opus approved exact 1ba2423a02d192c38664d010e64af7138fcd52c2 (…000309)
3 Freeze h1/h2/h3 contract shapes as contract beta.24 / SDK beta.7 and close review gaps 4e54f1d 7c789df 29d82fe (1ba2423..29d82fe) 3 commits; 54 files, +1,684 −184; contract/SDK plus the complete consumer pin closure Opus approved exact 29d82fe20c1f34aeab0adef2a04f2242dbffa9e9 (…000627); Fable independently verified the canonical artifacts (…000640)
4 Sync main #63 as contract beta.25 / SDK beta.8, fix loopback timing, and finish the extension escape-hatch audit 82ecb15 merge a9eecab d51a664 aae96e0 55862d3 736256a (29d82fe..736256a) 6 first-parent commits; 57 files, +1,168 −317; contract/SDK/consumer closure, loopback test, one Personal Chrome audit test Opus approved beta.25 exact 55862d36128bcb580434c408411b9bb67716834c (…000702) and the audit content later pushed byte-identically as 736256a (…000660, continuity …000713)
5 SDK h2 carrier repair: pass the granted Host data directory through the real module carrier and fail closed without the grant 6c02298 (383ef60..6c02298) 1 commit; 43 files, +371 −176; SDK implementation/tests plus 12 exact dependency re-pins and catalog closure Sol approved exact 6c022987cba19e646f8523f422c38d16826f9c50 (…000934); Astra independently verified the canonical artifact (…000937)
6 W2-3 p2a: module-plugin skeleton, manifest/capabilities, authorization list and per-row revoke, status/test/stop, install docs and real create().start() test direct commits f2adca6 e76cd3b e692308 dc1b3f2 7ca22be 666f7f0 9907d13, merge 262f721, then 303f0ec 383ef60 aef8d6a 10 direct commits plus 1 merge; direct-commit delta 19 unique files, +1,346 −25; merge conflict resolution covers 4 files. Primarily packages/personal-chrome-companion, plus catalog/release/fresh-consumer evidence Sol reviewed the merge in the p2a rounds (383ef60 changes requested → exact aef8d6a63a7d47a31888caa9e08ddc327a1b48a1 approved, …000022)
7 R3/version sync #1: account for the p2b implementer's interim beta.25 reuse, absorb upstream #64/#67 without reusing a frozen identity, then move to contract beta.26, SDK beta.10 and companion alpha.16 with an attested-identity guard c92a8c6, merge 75481fb, 7c16e03 3fc4b0b 0d30250, merge b5ad781, b7a08af f1e10d4 c53520d a17b998 (33abebb..a17b998) 10 first-parent commits; 53 files, +780 −231; contract/SDK/companion, 11 production consumers, catalog and release guards. Review 75481fb's six-file conflict resolution with this slice Sol requested changes at 0d30250 because the interim commits reused frozen beta.25 bytes (R3 …000132 / …000135); Opus chose forward-fix option A (…000137); Sol approved the sync at c53520d (…000220); Astra rejected and then verified closure at exact a17b9982c6981390e577fe1aa196d63840e87872 (…000223, …000239); Sol's later c53520d..afeaa70 approval explicitly includes that closure fix
8 W2-3 p2b: v2 protocol and real socket-backed append/list/ack, including stop cancellation and post-write ambiguity semantics direct commits 7c9c80b f226c8b f638d58 25a6c36 33abebb c6c3381 00c184d e4b3284 afeaa70 9 direct commits; 14 unique files, +2,025 −423; Personal Chrome source/tests plus its catalog pin and closure guard Sol approved exact afeaa705c9b74b4f7e7d502ce6a876ed249a4275 (…000298) after the R1/R2 red-to-green repair
9 Version sync #2: absorb upstream #68/#69; contract beta.27, SDK beta.11, companion alpha.18; extend the attested guard and move the frozen-toolchain instructions out of ephemeral /tmp 644d66a, merge b5f218e, e5ae546, 6fa5c46 (afeaa70..6fa5c46) 4 first-parent commits; 60 files, +973 −247; contract/SDK/companion, 11 production consumers, catalog/guards and CONTRIBUTING.md Sol approved exact 6fa5c46e0ec1fe53f8a52ea19f8010cc35ac1df7 (…000114); Astra independently verified the canonical artifacts (…000129)

For a first-parent overview:

git log --first-parent --oneline e2aef8f..6fa5c46

For p2a and p2b, use the explicit commit sets in the table rather than treating their work as one contiguous range; the intervening sync commits are separate review slices above.

First-parent completeness and merge audit

Every first-parent commit in e2aef8f..6fa5c46 belongs to exactly one slice above. The six merge commits are:

Merge Upstream parent git show --cc result / resolution scope
d25c4eb 264266347dcf1eada31a5f1646c4a2c1ac71afec non-empty combined diff: catalog/catalog.json, packages/companion/README.md, packages/companion/package.json
a9eecab 0487e482148334563dc38d47027aa4bf55164b35 non-empty combined diff: packages/companion/README.md, packages/plugin-contract/src/generated/contract.generated.ts
262f721 d5cc46aac57d8b746056dd98989f7993586067dd non-empty combined diff; four resolved files: .github/workflows/contract-ci.yml, migration/f202-train-c1-inventory.json, pnpm-lock.yaml, scripts/fresh-consumer-install.test.mjs
75481fb 0a2783978a78627378c76574a40104a847d9cab1 combined diff empty. Six conflict files were resolved to parent-compatible content: companion decision-view.mjs plus two tests, contract companion-bridge.schema.json plus its test, and SDK companion-client.test.ts. Please review this resolution with slice 7
b5ad781 791d63ce4397eaead1c363221b622b4488718f07 non-empty combined diff: catalog/catalog.json
b5f218e fdd1a83fa40711b755e20cf4afef7f231c7a4b15 non-empty combined diff: catalog/catalog.json, packages/companion/README.md, packages/plugin-contract/src/generated/contract.generated.ts

2. Acceptance checks already complete

All canonical packs below were produced with the frozen Node 24.18.0 / npm 11.16.0 / zlib 1.3.1-e00f703 toolchain and independently rebuilt before attestation.

Slice Reproducible evidence
p1 The migrated extension's 11 files and native host's 15 files are byte-identical to the Host source; 11 tests, 2 helpers and 1 fixture were moved with them. Exact-head CI: Contract 36171504155, Personal Chrome 36171504299, both success.
Sync #60–#62 Exact-head CI: Contract 36224064202, Companion 36224064197, both success. The merge was reviewed separately from the companion version bump.
beta.24 / beta.7 pnpm gate:ci 27/27 on the exact tree; targeted contract/SDK validation and artifact byte comparison passed. The PR was temporarily conflicting, so this slice has no exact-head GitHub run; that absence is explicit rather than being inferred green.
beta.25 / beta.8 + audit pnpm gate:ci 27/27. Exact-head CI at 55862d3: Contract 36326898937, Companion 36326898927; the audit-only successor 736256a has Contract 36327598966, Companion 36327598947. All passed.
SDK beta.9 carrier Real create(plugin.yaml).start(host) changed from the beta.8 PERMISSION failure to a successful start/list/stop; the no-grant case still throws PERMISSION. SDK-focused tests 49/49, fresh-consumer 1/1 and pnpm catalog:check 17/17 passed. Exact-head CI: Contract 36337656573, Companion 36337656615.
p2a pnpm --filter @clowder-ai/personal-chrome-companion test 137/137; the real entrypoint test covers granted-directory access, list/status/test, own-function contribution methods, contract validators and stop cleanup. pnpm gate:ci 27/27. Exact-head CI: Contract 36339676700, Personal Chrome 36339676692.
Version sync #1 The new attested-identity guard first fails on the old beta.25/new-bytes incident and passes after the version bump. pnpm gate:ci 28/28; all 11 production shrinkwraps close over the independently packed bytes. Exact-head CI at the final closure head a17b998: Contract 36397386904, Companion 36397387095.
p2b Nine real Unix-socket seam regressions cover stop races, malformed/truncated/post-write receipts and a typed-failure control. Package tests 161/161, production shrinkwrap gate 15/15, pnpm gate:ci 28/28. Exact-head CI: Contract 36404795396, Personal Chrome 36404795347.
Version sync #2 Attested-identity plus production-closure tests 18/18; companion-bridge contract tests 7/7; SDK companion-client tests 7/7; pnpm gate:ci 28/28; pnpm catalog:check 17/17 across all 11 production consumers. Exact-head CI: Contract 36689132119, Companion 36689132264.

Attested artifact coordinates

Package SHA-256 Size
@clowder-ai/plugin-contract@0.1.0-beta.24 d0dda313a6689efdf81dede6983cf2430ff5ae97d5ec529e1fbfcf9a34aaaeff 220,820 B
@clowder-ai/plugin-sdk@0.2.0-beta.7 d4d9a568f72cb523b6e08054e59f5c83144f300794d0a293f53a5d10bfbfbb84 54,762 B
@clowder-ai/plugin-contract@0.1.0-beta.25 80816b015dbf035b322a60e218e298be48d889499b3a12018118bf4648e71dde 222,009 B
@clowder-ai/plugin-sdk@0.2.0-beta.8 886bb594f53989dd318acadd875d6e36a679babfe011b890df39c5a267876f26 54,761 B
@clowder-ai/plugin-sdk@0.2.0-beta.9 8579f442d0a68c37d12a0e887685012d7d386939b621c0a3a7bad42e082a98b7 54,926 B
@clowder-ai/plugin-contract@0.1.0-beta.26 c190d21756023d3552cc6b3427d2441fee7b30099c3e5763bdbff9b64efe7927 222,014 B
@clowder-ai/plugin-sdk@0.2.0-beta.10 0c7c6e0a46d76d95f3c10502235be462749b84533d85095fc0653493e1d7e28e 54,928 B
@clowder-ai/plugin-contract@0.1.0-beta.27 5dedbe7e49e7153348608124db530415ed4aff57f451ca0b71e841412f7629f6 222,858 B
@clowder-ai/plugin-sdk@0.2.0-beta.11 c62e138e9ed0bccd9c3d11aeb9bfbf6d752b1d6a136837baefa2f791b6072482 55,056 B

The version-to-version member diffs were also independently checked: beta.24/beta.7 only the frozen h1/h2/h3 surface; beta.25/beta.8 only main #63 plus versions; beta.9 exactly 8 SDK members; beta.26/beta.10 exactly 2 contract and 1 SDK members; beta.27/beta.11 exactly 8 contract and 5 SDK members. No unlisted member was added, removed or changed in those syncs.

3. What we need from you

  • A scoped code review of the nine completed slices above. The local approvals and artifact attestations are evidence, not upstream approval or merge authority.
  • Please pay particular attention to three boundaries:
    1. the p1 extension/native-host files remain byte-identical to the Host copies while package-owned tests close the escape hatches;
    2. p2b never reports HOST_UNAVAILABLE after a request may have been written, and stop(reason) settles every in-flight request without leaking sockets;
    3. the attested-identity guard makes any frozen version whose bytes drift fail closed before publication.
  • No architecture decision is pending for these completed slices.

4. Remaining work — not waiting on this review

  • p2c is in progress and excluded from this request. Its three commits are currently at the live PR tip (68f15b6, 16287c4, 847176e; 8 files, +501 −46). They add lazy 2s→60s list backoff, honest helper status including invalid installation, transition-only logging and the catalog pin. It still needs its exact-head CI/local Sol verdict before it can be offered as ready.
  • p2d has not started: stable extension load path in the plugin data directory, update/reload and tested rollback behavior, the helper-update decision, package-owned extension checks and icon hashes. p2d owns the acceptance evidence needed by Host h3c-3.
  • Batch 6 artifacts come only after p2a–p2d are all approved: the seven connectors plus personal-chrome-companion, independently packed and verified by Astra.
  • Host h3c-3 then switches ChatGPT Pro to the package and removes the Host copy. The Host's h3c-1 and h3c-2 slices are already approved; h3c-3 intentionally waits on p2d and Batch 6.
  • Hands-on acceptance still needs the operator's real accounts for QR login and real IM send/receive.

This does not change the merge policy: #54 remains draft, and #54 plus #1487 merge together only after the remaining work and the operator's hands-on acceptance. No merge or publication is requested by this comment.

… on start

Why: keep the Chrome load path stable across updates and rollbacks, preserve pairing identity, and make owner reload requirements durable and truthful. Publish only within the granted data directory under the installer lease; drain ordered revision observations on stop.

Authored by astra (gpt-6-astra).
Why: bind the catalog to the final p2d-1 packed bytes after extension/helper delivery, reload observation, tests and README are complete.

Authored by astra (gpt-6-astra).
@mindfn

mindfn commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

Slice 10 ready for review — W2-3 p2c

Follow-up to the nine-slice review request: p2c has now completed local review and is ready as slice 10.

  • Exact HEAD: 847176ecae821800f24d11acac19540df3665033
  • Range: 6fa5c46..847176e
  • Commits: 68f15b6, 16287c4, 847176e
  • Scope: 8 files, +501 / -46

What changed

  • Added lazy helper-unavailable backoff for list calls: 2 / 4 / 8 / 16 / 32 / 60 / 60 seconds, without background timers.
  • Kept append, ack, and Test as live connection attempts; a real socket connection resets the backoff.
  • Added owner-visible helper states, including invalid_installation, with transition-only logging and safe repair guidance.
  • Preserved honest failure boundaries: business failures and post-write FIN/timeouts do not masquerade as pre-send unavailability.
  • Kept status observational (no socket side effect) and made stop clear state and cancel live requests.

Local approval and evidence

  • Independent local review: approved by sol at exact HEAD 847176e (thread verdict 0001790760139424-000190-2cdb6b3c), with no blocking findings.
  • Frozen-toolchain gate: 28/28 passed.
  • Personal Chrome package tests: 179/179 passed.
  • Exact-HEAD CI:
    • Contract CI 36693587002: success
    • Personal Chrome Companion CI 36693587091: success
  • Updated personal-chrome artifact pin: 132,603 B, SHA-1 f6025a8468e0b6713cc0e8ac214d78f99a524e5a.

Still pending

p2d-1 is currently in local review at a38c593 and is not part of this review request; the ready boundary here remains p2c at 847176e.

p2d, batch 6, Host h3c-3, and Landy's hands-on acceptance remain pending. This slice being ready for review does not change the merge policy: #54 remains draft, and #54 and #1487 still merge together only after hands-on acceptance. No merge or publish is requested here.

…epted observations

Why: helper activation failures must restore the prior extension under the same installer lease; stopping must persist STALE observations accepted before admission closes. Covers both review regressions and re-pins the packed artifact.

Author: astra / gpt-6-astra
Why: p2d removes the Host-owned extension copy, so the package must own its manifest, revision, generated bundle, executable budget, and icon identity checks. Port the deterministic generator with a direct pinned tool dependency while preserving the shipped script body byte-for-byte.

[砚砚/gpt-5.6-sol🐾]
Why: the package now owns the extension contract assertions and generator, so the catalog must identify the exact packed bytes whose content-script body, protocol revision, permissions, and icon hashes were verified.

[砚砚/gpt-5.6-sol🐾]
Why: delayed identity failures could log through a revoked Host context, and load-sensitive tests plus a single npm reset prevented reliable C1 validation. Drain cancelled identity work, exercise watchdog transitions with a clock, bound each connector test file, and retry only transient registry transport failures. Re-pin the un-attested Feishu alpha.1 artifact; keep versions and p2d surfaces unchanged.

Authored-by: astra (gpt-6-astra)
Why: release-config intentionally verifies package test script invocation. Scope the deadline preload through NODE_OPTIONS instead of replacing those entrypoints, and exercise that exact transport in the hung-file fixtures.

Authored-by: astra (gpt-6-astra)
Why: the explicit script inventory must execute the new hung-file fixtures on every full gate, not only during targeted local validation.

Authored-by: astra (gpt-6-astra)
@mindfn

mindfn commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

Two more finished slices ready for maintainer review (11–12)

This follows the per-slice review request in the earlier checklist and its p2c follow-up. The PR is still an aggregate and remains draft, but these two additional slices are locally complete and independently approved. The current PR HEAD is 7e045cd63059443d134e3421d2894725e6e95f22; that is also the ready boundary for this request.

Slice 11 — W2-3 p2d-1: extension/helper delivery and reload lifecycle

  • Range: 847176ecae821800f24d11acac19540df3665033..a6106da1db1886633ccbfca9e1f53f29b7776771
  • What: places the extension at the stable data-directory path; republishes an installed helper only inside that directory when its digest changes; preserves pairing identity; reports reload-required state; tests N→N+1 and rollback N+1→N. The final revision also closes whole-activation rollback and stop/drain races found during local review.
  • Local review: Sol approved exact HEAD a6106da1db1886633ccbfca9e1f53f29b7776771 (thread verdict 0001790768032901-000306-8caf1dbe), with no remaining findings.
  • Checks: frozen local gate:ci 28/28; package tests 197/197; the two review regression cases 2/2.
  • Exact-head CI: Contract CI 36707291426; Personal Chrome Companion CI 36707291592 — both succeeded on a6106da.
  • Attested package: 140,622 B / 76 members; SHA-256 c7c1785d686dd5cdeb37e2560de3b9c18b691238005455118860ef6463e389f4; SHA-1 6d114dee72f1f3912e523860d77d4807925fd471.

Slice 12 — W2-3 p2d-2: package-owned extension assertions and generator

  • Range: a6106da1db1886633ccbfca9e1f53f29b7776771..7e045cd63059443d134e3421d2894725e6e95f22
  • What: moves the extension contract assertions and content-script generator into @clowder-ai/personal-chrome-companion; pins icon SHA-256 values; regenerates content-script.js with only its provenance header changed. Excluding line 1, the old and new body SHA-256 are both 92b43e1701ad4c77bf77661a4018ab77d82b2e5ce5b08b2c8d4fc41ca9488224.
  • Local review: Sol approved exact HEAD 7e045cd63059443d134e3421d2894725e6e95f22 (thread verdict 0001790772164140-000356-d0e7d663), with no blocking findings.
  • Checks: package tests 204/204; typecheck/diff-check; nine negative guard cases; byte-identical explicit regeneration.
  • Gate of record: Contract CI ran the same full pnpm gate:ci on a clean runner and passed 28/28 in 443s. Three local full-gate attempts did not pass: one npm TLS reset, one existing Feishu late rejection, and one existing DingTalk timing/cleanup hang. Those failures are preserved as failures rather than relabelled green. Their root-cause stabilization is a separate in-progress slice and includes fixing a real Feishu connector runtime defect: a late bot-identity request after stop() could produce an unhandled rejection.
  • Exact-head CI: Contract CI 36713414324; Personal Chrome Companion CI 36713414329 — both succeeded on 7e045cd.
  • Attested package: 140,666 B / 76 members; SHA-256 1889bcb1d80a48fd5b7280835965a88bba7e5e69eb02044f3a272df70cd120df; SHA-1 736fa9ef1ee551c9c4add143ab2fa60f44ee2d51.

Boundary and remaining work

  • Please review slices 11 and 12 independently at the exact ranges above. Together with the earlier checklist and p2c follow-up, all p2a–p2d work is now locally approved.
  • The separate gate-stabilization slice is in progress and not part of this request. Batch 6 artifact verification and Host h3c-3 / production Chrome acceptance remain pending after it.
  • Merge policy is unchanged: this comment requests review only. PR feat(plugins): migrate F202 Train C1 package runtimes #54 stays draft; final merge remains coordinated with Host PR #1487 after hands-on acceptance. No publish or merge is requested here.

Why: repeated gates should not require a fresh TLS connection for immutable source bytes. Validate cached SHA-256 before reuse, retry only bounded transient transport failures, and retain all archive/source admission checks. Added deterministic offline, corruption, timeout, and fail-closed tests.

Authored-by: astra (gpt-6-astra)
Why: the release packer ignored canonical shrinkwrap resolution and archived wall-clock metadata, so registry drift and gzip timestamps could change self-contained bytes without a source change. Drive production installs from the shrinkwrap, restore canonical manifests, and normalize archive framing before hashing.

[砚砚/gpt-5.6-sol🐾]
@mindfn

mindfn commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

Two more finished slices are ready for review (slices 13–14)

The live PR head is 60d3bfecb9c153352317a1a96fbc94fb9a1b2fb9. These two slices extend the previously requested ready boundary through that exact head. The PR remains draft, and the merge policy is unchanged: #1487 and #54 merge together only after Landy's hands-on acceptance.

Slice 13 — gate stabilization, including a Feishu production lifecycle fix

  • Range: 7e045cd63059443d134e3421d2894725e6e95f22..2d51986ce7866e2e31b288a6b424a4fb6eb72fcd
  • Commits:
    • 2d451df fix(gate): own Feishu identity tasks and bound transient failures
    • d91fa8e fix(gate): preserve connector package test entrypoints
    • aaa77dd test(gate): include deadline regressions in CI script coverage
    • 2d51986 fix(genoffice): reuse verified source archives and bound downloads
  • Scope: 15 files, +527/-56. Feishu runtime/tests; DingTalk test timing/cleanup; per-file connector-test deadline; bounded registry retry; verified GenOffice source cache and bounded transport retry; catalog re-pin only where packed bytes changed.
  • Why it matters: Feishu's startup bot-identity request was not owned by the stop lifecycle. A late rejection could call a revoked Host logger and become an unhandled rejection in the in-process Host. The fix cancels and drains the request and fences late results by ingress epoch. The remaining changes remove three observed gate flakes without weakening fail-closed behavior.
  • Acceptance: deterministic red→green coverage for all five failure modes; Feishu 93/93, DingTalk 62/62, scripts 42/42, plus six independent runtime/network probes. Three consecutive loaded full gates passed 28/28 (551s / 310s / 313s). Exact-head CI: Contract 36720353038, Personal Chrome Companion 36720352999, both success.
  • Local approval: Sol approved exact 2d51986 with no blocking findings (thread verdict 0001790776008113-000402-0e16e043).

Slice 14 — reproducible self-contained release packing

  • Range: 2d51986ce7866e2e31b288a6b424a4fb6eb72fcd..60d3bfecb9c153352317a1a96fbc94fb9a1b2fb9
  • Commit: 60d3bfe fix(release): make self-contained packing reproducible
  • Scope: 2 scripts files, +370/-28; no package source, version, contract, SDK, or published npm-package byte changes.
  • Why it matters: the old packer used npm install against semver ranges, so registry drift changed self-contained bytes while the package shrinkwrap stayed fixed. The reviewed packer now uses production-only npm ci from the canonical shrinkwrap, exact local unpublished contract/SDK tarballs, restores canonical manifest/shrinkwrap bytes before archiving, and emits deterministic sorted/fixed-metadata archives. The strict verifier is unchanged.
  • Acceptance: script suite 43/43; full gate 28/28 (403s); two independent eight-package builds were byte-identical and content-equivalent to the manual baseline. Exact-head CI: Contract 36726328324, Personal Chrome Companion 36726327943, both success.
  • Local approval: Sol approved exact 60d3bfe with no blocking findings (thread verdict 0001790778933664-000425-32d803c9).

Batch 6 release evidence

The reviewed packer produced the non-draft prerelease f202-c1-connectors-batch6-60d3bfecb9c, targeting exact 60d3bfe. It contains seven connector alpha.1 archives, personal-chrome-companion alpha.0, and SHA256SUMS.

Astra independently rebuilt all eight canonical npm packages and all eight self-contained archives from a clean exact-HEAD worktree, without reusing the release files. All eight rebuilt archives equal the downloaded assets byte-for-byte; canonical SHA-256/SHA-1/SRI/member counts match the catalog; SHA256SUMS covers exactly the eight tgz files; and rebuilt plus downloaded archives passed the strict closure verifier 16/16 (no links, exact shrinkwrap closure, relocated main/runtime loading). Every archive embeds contract beta.27 and SDK beta.11. Canonical verdict: PASS at 60d3bfe (0001790779868113-000437-7d000819).

Self-contained SHA-256:

412fc483bb455b708797edf6d03eb5b921849ba2b151bac2418df732bc7a0001  connector-dingtalk alpha.1
96fea826c973c4ebcf580c8fe14a1d43fd21858b90a81d0307e673d1c6a4bf70  connector-feishu alpha.1
ea16a927b0acd93d3f4f677b061309680be99827252784ff88747185e987d5d5  connector-telegram alpha.1
2206b37d6d2a5c4cc7065babaf9bbba5ae4c89378cca63e6dbccb13dab91724f  connector-wecom-agent alpha.1
dfcfeed7458c4ff2f343dc9c5d9cade3f41508b7d1629eacba2892004422c77e  connector-wecom-bot alpha.1
341d32ac953fe1e60fb9de30581af9ad80a4ae24079018d85613eb080066a5bc  connector-weixin alpha.1
54e442698339a369e90e2936276a91208db63e1df42569432b31edb8b9c11131  connector-xiaoyi alpha.1
42f118310a348f6539d363a974b3c978b93969000f4f8d3a02f85f68522ce2b2  personal-chrome-companion alpha.0

The reproducibility claim is deliberately limited to the frozen macOS/darwin-arm64 toolchain; it does not claim arbitrary cross-platform tar/gzip/xattr byte identity.

Still pending on our side

  • Host h3c-3 hands-on Chrome/account acceptance and ledger gate swap from batch 5 to batch 6.
  • Upstream maintainer review and Landy's hands-on acceptance.
  • No merge or npm publish has occurred.

These pending integration/acceptance steps do not change that slices 13 and 14 are complete and locally approved at the exact ranges above.

mindfn added 3 commits October 1, 2026 00:31
Why: removing the Host copy must retain readable recovery titles. Reuse the paired helper exchange and stop/backoff boundaries, expose the existing titleSync union, and advance the attested alpha.0 package to alpha.1.
Why: bind the new owner action to frozen npm artifact bytes while retaining the independently attested alpha.0 coordinates from batch 6.
Why: p2e advances the already attested alpha.0 package; the consumer gate must assert the new approved version instead of the old fixture.
@mindfn

mindfn commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator Author

Slice 15 ready for review — p2e title refresh action

The ready-for-review boundary is now exact HEAD
6233d4881ea745a2d826eccaf8ff481152c0b054. PR #54 remains draft; this
comment does not authorize merge or npm publication.

Slice 15 — personal Chrome refresh-titles

  • Range: 60d3bfecb9c153352317a1a96fbc94fb9a1b2fb9..6233d4881ea745a2d826eccaf8ff481152c0b054
  • Scope: 15 files, +331/-10. @clowder-ai/personal-chrome-companion
    advances from 0.1.0-alpha.0 to 0.1.0-alpha.1; contract, SDK,
    extension and native-host bytes are unchanged.
  • What: adds the owner-triggered refresh-titles operation action used by
    the Host chat recovery card. It calls the existing paired helper protocol,
    returns the Host-compatible data.titleSync union, uses next: list, bypasses
    list backoff, and resets backoff after a successful connection.
  • Safety boundary: failures before sending are HOST_UNAVAILABLE; after a
    write they are never reported as safely retryable. Pairing rejection and the
    helper's own unavailable code are preserved, stop cancels in-flight work,
    and a successful v1 refresh does not falsely clear the reload-required state.
  • Independent review: Sol approved exact HEAD 6233d48 with no blocking
    findings (0001790787891622-000631-2554feb7). His additional 4/4 boundary
    cases covered the pairing exception, invalid result values, unsafe error
    classification and concurrent cancellation.
  • Evidence: package tests 221/221; full frozen-toolchain gate 28/28 in 258s;
    Contract CI 36746128757 and Personal Chrome Companion CI 36746128802, both
    successful on exact HEAD. The first full gate correctly failed on a stale
    fresh-consumer alpha.0 assertion; the final commit updates it to alpha.1 and
    the complete gate then passes.
  • Canonical artifact: 142,468 B / 80 members; SHA-256
    b3eb2e0f9593542031aed039ae89a69e78e2d635c8d1b29cc889be0ceb43c996;
    SHA-1 eda6ff801e484924f4ba651ea3dd0e1c9fad3672; integrity
    sha512-kyWV21jkiVFO8nLaIfwwN4Tvig1QQR9He0HASxdrZ3XuozI/hvcm+AQuyRE6rBBv91G3olDGIXqkgsjXiz5SlA==.

Batch 7 release

The independently verified pre-release contains only personal Chrome companion
alpha.1; the seven connectors remain on batch 6:

  • f202-c1-batch7-6233d4881ea7
  • self-contained SHA-256:
    ac3e52a622b2fa2876c3d085f400c3fa70af2025d95e89f603fd44c5c72cbe95
  • Astra independently rebuilt canonical and self-contained artifacts from the
    exact source, matched the downloaded asset byte-for-byte, and passed strict
    closure checks for both rebuilt and downloaded copies (0001790789059324-000663-6aa12b37).

Production Chrome and Host h3c acceptance remain outside this slice. The next
external step is for the Host to pin batch 7 for personal Chrome while retaining
batch 6 for the connectors.

mindfn added 6 commits October 7, 2026 11:35
…bins

Why: real Host acceptance exposed a missing rows-renderer declaration in personal-chrome. Merge exact upstream 8ee84f6 before the required push, retain both C1 and upstream capabilities, and version all changed attested artifacts. The package-bin audit also found build-state-dependent executable modes; normalize declared bins after builds and reject non-executable archives. Preserve historical catalog coordinates and existing releases.
Why: preserving both main and C1 history appended newer upstream companion entries after older versions, violating catalog semantic ordering. Reorder records without changing any historical coordinates or package bytes.
Why: valid subpath-only dependencies were rejected after successful entrypoint imports. Retain exact physical closure and real main/runtime import checks, require all direct packages in the checked installed set, and cover missing subpaths, packages, version drift and escaping links.
Why: Xiangqi declares its valid library entry as a string root export rather than main or a conditional import object. Exercise that actual entry and keep missing-entry rejection; cover both exports shorthand and root-map forms.
Why: Fresh Chrome setup must be reachable through the owner-confirmed Host journey rather than README commands. Supply a bounded install/inspect/uninstall protocol with stable identity, registration ownership and preserved user data; keep browser loading explicit and connection status honest. Attest the new alpha.3 identity with canonical and real archive setup coverage.
Why: Independent review reproduced a helper-start race during setup and a successful uninstall that retained an owned orphan registration. Hold the existing helper socket fence across mutations, validate borrowed inactive leases, remove owned orphan registrations, and cover both race orders and data-preserving cleanup with deterministic regressions.
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.

1 participant