A failing pull-request admission run keeps every already-launched sibling
job running to completion: production data showed 14% of job-minutes went
to cancelled runs and failed runs burned 100+ doomed job-minutes after the
first red check, because GitHub has no cross-job fail-fast and matrices
deliberately keep fail-fast disabled so every broken shard reports.
Each substantive job now has a dedicated fail-fast-* tripwire that cancels
the whole run through gh run cancel the moment that job fails. One tripwire
per job is required because a job-level needs evaluates only after every
watched job completes. Tripwires depend on lint directly and fire only for
pull-request events after a successful lint classification: protected-main
pushes run to completion as the coverage-cache producer and keep the full
failure picture for triage. A cancelled admission run still fails the nine
required ruleset contexts, so the mechanism can never authorize a merge.
TestCIFailFastTripwiresWatchEverySubstantiveJob derives the watched set
from the live job graph: a new substantive job without a tripwire, or a
tripwire orphaned by a removed or exempted job, fails the contract tests.
Protected-main pushes fire within seconds of the merge, before GitHub's
commit-to-PR association index necessarily lists the fresh merge commit.
Both production attempts since the reuse mechanism landed fell back to the
complete main suite with "expected one associated merged PR, found 0" even
though the PR records already bound the exact merge identity.
Discovery now re-polls on a bounded budget (twelve attempts five seconds
apart by default, tunable through DWS_ADMITTED_MERGE_RETRY_*) and also
consults the most recently updated closed main PRs under the identical
exact filter, since the merge transaction records merge_commit_sha on the
PR before the push event fires. Only zero-match discovery retries;
ambiguous results still throw immediately and an exhausted budget keeps
the complete protected-main suite, so fail-closed semantics are unchanged.
Reviewer Router treated mergeable=false dirty PRs as synchronous merge candidates, so an expected denial became an unsupported 403 and failed the repository-wide batch. Classify explicit non-ready states before merge and recover the same state transition race without hiding unproven App authorization failures.
- allow oa.list_pending_approvals to redirect from list_pending_approvals to get_todo_tasks
- preserve the stable canonical command identity
- add regression coverage for the exact reviewed interface_ref mapping to #666
Allow `dws chat emotion favorite` to accept a local image through
--file-path as an alternative to --media-id. The local file is
validated (extension whitelist, size <= 10MB) and uploaded via the im
upload_media tool (bizType=chat_image, mediaIdV1 fail-closed), then
the existing favorite_personal_emotion flow is reused unchanged.
--media-id and --file-path are mutually exclusive and one of them is
required. Schema-wise this relaxes media-id from required to optional,
adds the file-path parameter as a reviewed mapping exclusion, and
declares the mutually-exclusive/require-one-of constraints with a
reviewed schema-compat transition.