sync: merge main into develop (unblock daily sync) - #73
Conversation
* fix(opencode): tolerate older auto-approval flags Why: zts212653#1100 showed the zts212653#1065 preflight turned missing --auto into a startup blocker. Select the best advertised approval flag and preserve previous no-default-flag behavior when none exists. [砚砚/GPT-5.5🐾] * test(public): sync source gate fixtures Why: zts212653#1101 was rebased onto current clowder main after the source PR merged, but the public repo still carried stale source-synced test gate fixtures. Sync the F236 public-test exclusion date and drift-route owner test setup from source main so the downstream hotfix can pass the normal public CI gate without changing the OpenCode behavior patch. [砚砚/GPT-5.5🐾] --------- Co-authored-by: MaineCoon-GPT-5.5 <26771442+zts212653@users.noreply.github.com>
Why: Zhipu/GLM OpenAI-compatible endpoints are versioned at /api/paas/v4 (and coding /api/coding/paas/v4), so provider setup must not display or regress into /v4/v1/chat/completions. Register zhipu/glm as first-class OpenCode provider suggestions and lock runtime baseUrl passthrough with regression coverage. Source: cat-cafe d1692107d0fc294d328af0c05ac1565839f1c5b7 [砚砚/GPT-5.5🐾] Co-authored-by: MaineCoon-GPT-5.5 <26771442+zts212653@users.noreply.github.com>
zts212653#1120) Why: Claude CLI <=2.1.177 reports contextWindow=200000 for claude-fable-5 (native 1M), and the CLI report outranks the fallback table in invoke-single-cat -- so all four fable5 variants sealed budget_exhausted at ~190K, wasting 80% of the real window. Production proof: sessions 59a48070/6b8d4b5f (thread_mraghcf19yl6ukzu) consumed 303K/307K input tokens in the very turns that claimed windowTokens=200K (fillRatio 1.0), truncating the same co-creator answer twice. How: KNOWN_MIN_CONTEXT_WINDOWS floors (claude-fable-5=1M; any [1m]-suffixed model=1M -- the suffix is the CLI's own 'run at 1M' directive) applied via resolveContextWindow() as max(reported ?? fallback, floor). Never shrinks a CLI report; becomes a no-op once the CLI catches up. Real fix is the CLI upgrade (2.1.177 -> 2.1.204, separate ops action); this is defense-in-depth. [宪宪/Fable5🐾] Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Why: PR tracking was marking merged/closed PR tasks done without an owner-visible terminal lifecycle delivery path, and source-first review found the review-feedback close path could mark tracking done before CI lifecycle recovery recorded the terminal state. The source counterpart has landed, this public PR has been synced to c4f000f, and GitHub CI is green.\n\n[砚砚/GPT-5.5🐾]
…eep_observe (#64) The 2026-07-09 window is clean on current counters: C2 forced-pass is 0/61 and void-hold is 0/61, with no C1 zombie-hold finding and no grounding mismatches. Trend interpretation is downgraded because the API process restarted during the trace window: trace coverage is 21.62h, but counter_window is 18.80h and the C2 denominator is far below the prior high-traffic windows. [published via cat_cafe_publish_verdict MCP]
…th-recurring-reference-only — keep_observe (#67) The every-3d friction window from 2026-07-06 03:00 UTC to 2026-07-09 03:00 UTC surfaced one new high-severity actionable singleton (`a2a_timeout: codex`) from the `Coactive 架构` thread, while the other four top clusters were recurring `eval:a2a` reference-only counters (`c2.void_hold_hint_emitted` plus three `inline_action.*` signals). The rollup remained degraded and the timeout had no second-channel echo, so the new signal looks like an isolated interruption rather than a stable cross-channel friction pattern. [published via cat_cafe_publish_verdict MCP]
…s212653#1075) * feat(F237): Phase 2 — Hook Pipeline migration with trace bridging Migrates prompt injection from ad-hoc if/push in SystemPromptBuilder to a structured HookPipeline with 46 typed manifests, resolvers, and trace bridging to v0 InjectionTrace persistence. Key changes: - HookRegistry: scans assets/prompt-hooks/ for 46 hook.yaml manifests - HookPipeline: resolve → fire → trace execution engine - PipelinePromptBuilder: drop-in replacement for legacy builder - Scope filters: S-prefix for session-init, D-prefix for per-turn - Trace bridging: pipeline drains to v0 trace (sole persist path) - Concierge ordering: spliced between D17/D18, matching legacy Runtime overrides (HookOverrideStore) deferred to PR 3 per maintainer scope gate. All deliverable rows, ACs, and architecture sections updated to reflect baseline-only APIs in PR 2. 170 F237 tests pass. Zero behavior change (AC-P2-14). [宪宪/claude-opus-4-6🐾] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(F237): manifest endpoint → HookRegistry, hook content fallback Why: sync commit c9d1003 deleted assets/prompt-injection-manifest.yaml (replaced by 46 individual hook.yaml files in Phase 2), but the /api/prompt-injection/manifest endpoint in rules.ts still read the old file → 404. Additionally, resolveHookContent only handled H-prefix sourceType='hook' segments, so R1/R2/B1 (templates in hook dirs, not in prompt-templates/) returned "not template-backed" errors. Changes: - New prompt-injection-manifest.ts route: scans HookRegistry, maps HookManifest → ManifestSegment (derives category/consumer/sourceType from ID prefix), returns schemaVersion 2.0.0 - Rewrite prompt-injection-hooks.ts: resolveHookContent now uses HookRegistry to locate templates in hook dirs (fallback for segments not in TEMPLATE_FILES) - Remove old manifest endpoint from rules.ts (also removes unused YAML import, bringing file under 350-line limit) Tests: 120/120 F237-specific tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(f237): supplement manifest with 6 non-hook segments (N2/M1/M2/H1-H3) Why: Codex P1-2 correctly identified that the manifest endpoint only returned 46 HookRegistry segments, while the feature spec declares 52 segments total. The missing 6 are outside the hook pipeline: - N2: conversation history delta (observe-only, route-assembler) - M1: dispatch mission context (observe-only, invocation-layer) - M2: transcript path hints (observe-only, invocation-layer) - H1: Claude Code SessionStart hook (external, shell-hook) - H2: Claude Code PostCompact hook (external, shell-hook) - H3: Claude Code SessionStop hook (external, shell-hook) Added SUPPLEMENTAL_SEGMENTS array with full ManifestSegment metadata for all 6. Response now includes totalActive (46 hooks), totalObserveOnly (3 adapters), and totalExternal (3 shell hooks) for clear categorization. [布偶猫/Claude Opus 4.6🐾] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(f237): cascade manifest contract change to frontend + feature doc Why: R2 review correctly identified two contract-consistency gaps from the manifest supplementation fix: 1. Frontend ManifestResponse still referenced `totalLegacy` (removed from API), causing `undefined 遗留` in Console badge. Updated to use new `totalObserveOnly` + `totalExternal` fields. 2. Feature doc still claimed 49/52 complete trace observability via observe-only adapters, but adapters have no production call-sites. Added caveats at 6 locations (motivation, scope summary, trace architecture, P2-C description, AC-P2-4, AC-P2-13) clarifying: adapter API + unit tests delivered, production wiring deferred due to execution order constraints. Failure-mode audit: scanned all consumers of manifest response shape and all 49/52 trace claims — no additional uncascaded references found. [布偶猫/Claude Opus 4.6🐾] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(f237): preserve D2 direct-message hint for unknown senders Why: Legacy builder emitted D2 (direct-message source) with raw catId and 'unknown' model when the sender wasn't in catRegistry (stale/pending A2A handoff). The new context-assembler returned null instead, suppressing D2 entirely and losing the routing hint for the receiving cat. Fix: Return a fallback DirectMessageInfo with raw catId as label and 'unknown' as model, matching legacy behavior. D3 (same-breed warning) still correctly skipped since breed can't be determined without config. Red→Green: 3 new tests in context-assembler.test.js confirming unknown-sender fallback, self-sender null, and no-sender null. 137 F237 tests pass with no regressions. [布偶猫/Claude Opus 4.6🐾] Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Lysander Su <773678591@qq.com>
…212653#1129) Add shared withHiddenGhCliWindow() option constructor that forces windowsHide: true on every Node child-process invocation of gh CLI, and apply it to the direct gh calls across the API. This prevents transient conhost/OpenConsole flashes on Windows when gh telemetry launches child processes. Also aligns the remaining index.ts sync gh calls with getGitHubExecOptions() token isolation. Fixes zts212653#1130 Source PR: zts212653#1129 Head: fdeead5 Co-authored-by: Claude <noreply@anthropic.com>
… — keep_observe (#68) The 2026-07-11 eval:a2a window is clean but low-traffic: C2 forced-pass and void-hold counters are 0/16, C1 zombie/cancel counters are 0, and grounding mismatch_sample_count is 0 across two stored grounding samples. The domain registry still has legacyScheduledTaskIds=[], so this is the ordinary daily trigger rather than a duplicate legacy scheduled task. [published via cat_cafe_publish_verdict MCP]
…ack-improved-baseline — keep_observe (#69) The every-3d friction window from 2026-07-09 03:00 UTC to 2026-07-12 03:00 UTC collapsed to one medium-severity actionable singleton, `text_frustration: 错了 什么情况`, with no reference-only eval-domain clusters and no long-tail spillover. Compared with the previous 72h window's 9 signals and 5 clusters, overall friction volume clearly improved even though one user-feedback incident remained. [published via cat_cafe_publish_verdict MCP]
…ep-observe — keep_observe (#70) The 2026-07-12 eval:a2a window is clean with a recovered C2 denominator: forced-pass is 0/108, void-hold is 0/109, C1 zombie/cancel counters are 0, and grounding mismatch_sample_count is 0 across four stored grounding samples. The domain registry still has legacyScheduledTaskIds=[], so this daily run is not a duplicate legacy trigger. [published via cat_cafe_publish_verdict MCP]
…#71) QC pipeline metrics remain in zero-baseline state — no review telemetry events collected during the Jul 5–12 window. Phase C bootstrap: the qc-metrics-provider returns zeroes for all 4 metrics (finding yield, false positive rate, reviewer delta, post-merge bug rate) because no live data source is wired yet. [published via cat_cafe_publish_verdict MCP]
…rve — keep_observe (#72) The latest 24h anchor-first window appears low-volume and concentrated in thread-context preview traffic, while independent blindness evidence is absent because eval:task-outcome has not yet produced published verdict trends. Current evidence is enough to watch adoption and open-rate detail, but not enough to justify sunset or a corrective fix. [published via cat_cafe_publish_verdict MCP]
Conflicts resolved: - docs/ROADMAP.md: keep all entries from both sides, use develop's updated F241 description, add F237 from upstream - CiCdRouter.ts: keep develop's buildCiMessageContent with headSha support (inline, not extracted to ci-message-content.ts yet) - git-worktree-publisher.ts: combine withGhRepo (develop) + withHiddenGhCliWindow (main/upstream) for both features Root cause: main and develop diverged (14 vs 71 unique commits), blocking the automated sync workflow's daily main→develop merge step. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 561787d06a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import type { FastifyBaseLogger } from 'fastify'; | ||
| import type { ITaskStore } from '../../domains/cats/services/stores/ports/TaskStore.js'; | ||
| import type { ICommunityEventLog } from '../../domains/community/CommunityEventLog.js'; | ||
| import { buildCiMessageContent, buildLifecycleMessageContent } from './ci-message-content.js'; |
There was a problem hiding this comment.
Remove duplicate CI content import
This import collides with the existing export function buildCiMessageContent still declared later in the same module, so the API package no longer builds or loads (TS2440/ESM duplicate identifier). Any startup path that imports infrastructure/email will fail before CI routing can run; either remove this named import/re-export or remove the old local function as part of the extraction.
Useful? React with 👍 / 👎.
Two merge points now handle conflicts automatically instead of failing: 1. upstream→main: conflicts resolve with -X theirs (upstream wins). main's job is to track upstream; fork-specific code belongs on develop. The gate step still validates the result before pushing. 2. main→develop: conflicts resolve with -X ours (develop wins). develop is the active fork branch; upstream changes that conflict with fork code should not silently overwrite them. Both try a clean merge first — the -X strategy only kicks in when there are actual conflicts, logged via GitHub Actions ::warning::. This prevents the sync workflow from failing for weeks when branches diverge (as happened 2026-07-08 through 2026-07-12 with 10+ failures). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2bfd3c7a58
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (trackingInstructions) { | ||
| lines.push('', '📌 **Tracking Instructions**', trackingInstructions); |
There was a problem hiding this comment.
Preserve head-SHA gating for CI instructions
When tracking instructions were registered for an older PR head, the router still passes trackingInstructionsHeadSha into buildCiMessageContent, but this extracted helper ignores that value and appends instructions whenever the text exists. In the stale-head scenario already covered by the existing CI router tests, a later CI notification for a new commit would tell the cat to follow instructions meant for the previous SHA; keep the old instructionsHeadSha === poll.headSha guard in the extracted builder.
Useful? React with 👍 / 👎.
Why: PR #73 merges origin/main's extracted CI message builders with develop's tracking-instruction head guard. Keeping both the import and the old inline builder redeclared buildCiMessageContent and broke TypeScript, while dropping the guard would reintroduce stale instruction delivery. Move the head-bound instruction check into ci-message-content.ts and keep CiCdRouter as the re-exporting integration point.
Summary
mainanddevelopthat have been blocking the dailysync-upstream-main.ymlworkflow since 2026-07-08Conflicts resolved
docs/ROADMAP.mdCiCdRouter.tsbuildCiMessageContentwithtrackingInstructionsHeadSha+shouldAppendTrackingInstructionsgetConnectorDeliveryTargetrefactoring (upstream extraction to ci-message-content.ts deferred)git-worktree-publisher.tswithGhRepofor--repoflag supportwithHiddenGhCliWindowfor Windows compatibilityRoot cause analysis
mainhas 14 unique commits (upstream sync merges + eval verdicts)develophas 71 unique commits (feature work, fixes, manual syncs)Additional issue (separate fix needed)
developinstead ofmain— cron triggers run fromdevelop(doesn't affect workflow logic but is incorrect)Test plan
sync-upstream-main.ymlto confirm the daily sync workflow succeeds end-to-end🐾 [宪宪/claude-opus-4-6]