Skip to content

auto-arm: arm only on a reviewed, answered head (step 3/3) - #6063

Merged
rbuergi merged 10 commits into
mainfrom
fix/arm-after-review-lane
Oct 7, 2026
Merged

rbuergi merged 10 commits into
mainfrom
fix/arm-after-review-lane

Conversation

@rbuergi

@rbuergi rbuergi commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Step 3 of 3 of "arm only on a reviewed, answered head": auto-arm.yml stops arming and only disarms on a push. Arming is the control plane's job: MeshWeaver.Plugins PrArming (#2828, merged) applies check-review-answered.py --arm-gate.

What changes

  • auto-arm.yml keeps its file name, so no caller changes. It runs only on synchronize. If the pull request is armed, it runs gh pr merge --disable-auto and reads auto_merge back over REST.
    • It has no continue-on-error: a disarm that fails quietly would let an unreviewed head merge on a reviewed head's arm.
    • It still uses the meshweaver-cloud token with contents: write and pull-requests: write. No checks permission is needed.
  • lane-caller-grants.yml: the RETIRING and ARRIVING checks: read rows are dropped. Every auto-arm.yml row is {contents: write, pull-requests: write}, which is what the callers grant today. check-workflow-permission-pairing.py --fleet exits 0.
  • Guards:
    • NoWorkflowArmsAutoMerge: no workflow in .github/workflows arms auto-merge.
    • TheAutoMergeLaneDisarmsOnEveryPushAndToleratesNoFailure pins the disarm.
    • The #2916 App-token guards are kept.
  • Docs:
    • ReviewFindingsAnswered → "The arm gate" names the predicate the control plane applies.
    • The pullrequest skill, AGENTS.md (merge-queue line), FleetCiProcess, MergeQueue and HybridGitHubAzureDevOps no longer say auto-arm.yml arms every non-draft PR.

Adapted to Copilot as the reviewer (policy copilot-code-review, after #6229). The arm-gate conditions in the doc, the script comments and the guard message now name the review of the head as a Copilot review against the current head, or a completed internal-review run. They also add condition 5, every required check green (policy review-then-suites). The hard-coded policy dates this PR had added are replaced by policy ids.

Merge precondition: SATISFIED. PrArming now accepts a Copilot review of the head (Plugins#3088, merged), and the control instance has run it since its 13:30Z roll at core cac0664. The workflow armer can therefore be removed without leaving Copilot-only fleet PRs unarmed. This pull request also disarms fork pushes, since a maintainer can arm a fork PR by hand.

Verified locally (merge of origin/main 2026-10-07):

  • Workflow YAML parses.
  • check-review-answered.py --self-test: 226 ok, 0 FAIL, exit 0.
  • check-workflow-permission-pairing.py --root . and --fleet both report 0 violations.
  • check-workflow-timeouts.py: 0 violations.
  • MeshWeaver.Documentation.Test: Release -warnaserror build, 0 warnings, 0 errors; ArmedMergeMustTriggerMainsPushLanesGuard + DocumentationLink*: 10 of 10 passed.

Deploy: nothing beyond the merge. Every caller floats on @main.

🤖 Generated with Claude Code

rbuergi and others added 2 commits October 4, 2026 01:39
…wed push

Step 3 of 3. The lane asks check-review-answered.py --arm-gate (fetched from core
main, self-tested on every run) before arming, and arms only when the PR is not a
draft, the systemorph-com App's internal-review check run on the CURRENT head has
completed and is not the neutral "Reviewer unavailable" degradation, and every
thread the automatic reviewer opened has a person's reply. Otherwise one line in
the job summary names the missing condition.

Re-evaluates on check_run completed (only the internal reviewer's internal-review
reaches a runner), pull_request_review_comment created, and pull_request_target
ready_for_review/synchronize/opened/reopened. On synchronize an armed PR whose new
head is not ready is disarmed (GitHub keeps auto-merge across a push).

The lane now demands checks: read (the App token has no checks permission); the
roster's RETIRING rows are dropped and the ARRIVING rows are no longer pending.
Doc: ReviewFindingsAnswered gains "The arm gate".

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

  3 files  ±0    3 suites  ±0   7m 31s ⏱️ +9s
571 tests +2  380 ✅ +2  191 💤 ±0  0 ❌ ±0 
575 runs  +2  384 ✅ +2  191 💤 ±0  0 ❌ ±0 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

    5 files  ± 0      5 suites  ±0   4m 39s ⏱️ +36s
1 230 tests +44  1 230 ✅ +44  0 💤 ±0  0 ❌ ±0 
1 231 runs  +44  1 231 ✅ +44  0 💤 ±0  0 ❌ ±0 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

This pull request removes 15 and adds 59 tests. Note that renamed tests count towards both.
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ANodeTypeFailingOnADifferentSymbol_IsNotAccusedOfTheSamePartitionsRefusal
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ANodeTypeParkedOnARefusedSource_NamesTheImportAndTheReason
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ARefusalReasonCarryingAControlCharacter_IsRecordedAsReadableText
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_IsStillDerivable_WhenTheCallersHubDiesBeforeTheLegsSubscribe
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_IsStillDerivable_WhenTheCallersHubIsAlreadyDown
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_NamesTheInstance_WhenTheCallersHubIsAlive
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ AnOwnerThatIsRecycling_IsNamedAsSuch_NotAsUnknown
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ AuthorizationStillWins_AndAPlainFaultIsStillUnknown
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ EveryOtherDeliveryFailure_StaysUnknown
MeshWeaver.Graph.Test.ARequestCannotNameItsOwnAuthorTest ‑ ANodeCarryingAForgedAuthor_IsRecordedUnderTheCaller
…
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ABuildNodeWithNothingReported_WakesNoArbitrationPass
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AChunkCloseOut_RecordsItsReleasePaths_AndFreesTheChunk
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ACompletionReportedFromAStaleCopy_StillLandsItsGo
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AFailureReport_RecordsTheError_PublishesNoGo_AndFreesTheClaim
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AGrantIsNotPublishedOverAnUnfoldedReport
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AReportedOutcome_ChangesTheTriggerKey
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AReportedOutcome_WakesTheArbiter_WithNobodyQueued
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ASupersededBuildersReport_LandsOnNothing_AndIsConsumed
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AnUnreadableMirror_IsLeftUntouched
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ OnTheDurablePath_TheFoldFreesTheBuild_AndItsOwnWriteWakesThePassThatElects
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

    4 files  ± 0      4 suites  ±0   15m 56s ⏱️ -54s
3 604 tests +35  3 604 ✅ +35  0 💤 ±0  0 ❌ ±0 
3 607 runs  +35  3 607 ✅ +35  0 💤 ±0  0 ❌ ±0 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

This pull request removes 39 and adds 50 tests. Note that renamed tests count towards both.

   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
   --- End of inner exception stack trace ---, isDenial: True)
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
 ---> (Inner Exception #1) System.ArgumentException: Value does not fall within the expected range.<---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
 ---> (Inner Exception #1) System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known<---
…
Memex.Portal.Shared.Test.SessionDenialIsAnAnswerTest ‑ OnlyAVerdictReadsAsADenial(shape: "the same verdict nested, as a late denial dispatch"···, failure: System.InvalidOperationException: write failed
 ---> System.UnauthorizedAccessException: Access denied
   --- End of inner exception stack trace ---, isDenial: True)
Memex.Portal.Shared.Test.VersionSelectTest ‑ AMajorPattern_CrossesFromTheOldNotationToTheNew
Memex.Portal.Shared.Test.VersionSelectTest ‑ Stable_NeverSelectsANewNotationBuild
Memex.Portal.Shared.Test.VersionSelectTest ‑ TheNewNotationsEdgeBuild_IsGatedLikeTheOld
Memex.Portal.Shared.Test.VersionSelectTest ‑ TheOldFleetPattern_NeverSelectsTheNewNotation
Memex.Portal.Shared.Test.VersionSelectTest ‑ WideningThePattern_BeforeTheCutOver_ChangesNothing
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall as an aggregate's FIRST member", fault: System.AggregateException: One or more errors occurred. (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.
   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall as an aggregate's SECOND member", fault: System.AggregateException: One or more errors occurred. (The operation has timed out.) (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> System.TimeoutException: The operation has timed out.
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---
, expected: True)
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall nested in an aggregate inside a wrapper", fault: System.InvalidOperationException: outer
 ---> System.AggregateException: One or more errors occurred. (Value does not fall within the expected range.) (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> System.ArgumentException: Value does not fall within the expected range.
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---

   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall wrapped as InnerException", fault: System.InvalidOperationException: outer
 ---> MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.
   --- End of inner exception stack trace ---, expected: True)
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 844 tests   - 14   1 842 ✅  - 14   4m 17s ⏱️ - 1m 23s
    4 suites ± 0       2 💤 ± 0 
    4 files   ± 0       0 ❌ ± 0 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

This pull request removes 32 and adds 18 tests. Note that renamed tests count towards both.
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ABuildNodeWithNothingReported_WakesNoArbitrationPass
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AChunkCloseOut_RecordsItsReleasePaths_AndFreesTheChunk
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ACompletionReportedFromAStaleCopy_StillLandsItsGo
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AFailureReport_RecordsTheError_PublishesNoGo_AndFreesTheClaim
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AGrantIsNotPublishedOverAnUnfoldedReport
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AReportedOutcome_ChangesTheTriggerKey
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AReportedOutcome_WakesTheArbiter_WithNobodyQueued
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ ASupersededBuildersReport_LandsOnNothing_AndIsConsumed
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ AnUnreadableMirror_IsLeftUntouched
MeshWeaver.Graph.Test.AHoldersCompletionLandsOnTheOwnerTest ‑ OnTheDurablePath_TheFoldFreesTheBuild_AndItsOwnWriteWakesThePassThatElects
…
MeshWeaver.Graph.Test.AHeldTypeStaysOwnedUntilPrunedTest ‑ AHeldType_ARunThatDoesNotReHoldIt_StillPrunedOnceTheInstancesAreGone
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ANodeTypeFailingOnADifferentSymbol_IsNotAccusedOfTheSamePartitionsRefusal
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ANodeTypeParkedOnARefusedSource_NamesTheImportAndTheReason
MeshWeaver.Graph.Test.AParkedNodeTypeNamesTheImportThatLostItsSourceTest ‑ ARefusalReasonCarryingAControlCharacter_IsRecordedAsReadableText
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_IsStillDerivable_WhenTheCallersHubDiesBeforeTheLegsSubscribe
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_IsStillDerivable_WhenTheCallersHubIsAlreadyDown
MeshWeaver.Graph.Test.ARecycleCascadeEnumeratesFromASurvivorTest ‑ TheNetwork_NamesTheInstance_WhenTheCallersHubIsAlive
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ AnOwnerThatIsRecycling_IsNamedAsSuch_NotAsUnknown
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ AuthorizationStillWins_AndAPlainFaultIsStillUnknown
MeshWeaver.Graph.Test.ARecyclingOwnerIsNotAnUnknownRefusalTest ‑ EveryOtherDeliveryFailure_StaysUnknown
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    2 files  ±0      2 suites  ±0   8m 50s ⏱️ +7s
1 119 tests +5  1 119 ✅ +5  0 💤 ±0  0 ❌ ±0 
1 120 runs  +5  1 120 ✅ +5  0 💤 ±0  0 ❌ ±0 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

    4 files  ± 0      4 suites  ±0   6m 12s ⏱️ - 3m 34s
2 614 tests +12  2 614 ✅ +15  0 💤 ±0  0 ❌  - 3 
2 618 runs  +12  2 618 ✅ +15  0 💤 ±0  0 ❌  - 3 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

This pull request removes 5 and adds 17 tests. Note that renamed tests count towards both.
Memex.Portal.Shared.Test.InstanceIdRulesMatchTheRegistryTest ‑ TheSetupHostAgreesWithTheRegistry(candidate: "01cb1217-98ef-4103-a980-e6d2bcbca9ea")
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ APullRequestOnANonDefaultBaseIsToldWhyItWasNotArmed
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ NoWorkflowArmsAutoMergeWithoutReadingTheDefaultBranch
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ TheArmLaneArmsOnlyOntoTheRepositoryDefaultBranch
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ TheArmReadBackRecognisesOrdinaryAutoMergeAndMergeQueueAdmission
Memex.Portal.Shared.Test.InstanceIdRulesMatchTheRegistryTest ‑ TheSetupHostAgreesWithTheRegistry(candidate: "cdd651a0-2ce2-47d7-9304-4b9e897c7982")
MeshWeaver.Deployment.Contract.Test.FeatureFlagsTest ‑ ARecordKeepsItsFeatureFlagsThroughTheContract
MeshWeaver.Deployment.Contract.Test.FeatureFlagsTest ‑ ARecordWithoutFlagsReadsExactlyAsBefore
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ NoWorkflowArmsAutoMerge
MeshWeaver.Documentation.Test.ArmedMergeMustTriggerMainsPushLanesGuard ‑ TheAutoMergeLaneDisarmsOnEveryPushAndToleratesNoFailure
MeshWeaver.Documentation.Test.AutomationSwitchesReachTheConfigMapGuard ‑ AnExplicitNullOnTheRecord_IsOmittedFromTheConfigMap
MeshWeaver.Documentation.Test.AutomationSwitchesReachTheConfigMapGuard ‑ AnUnquotedFalseOnTheRecord_RendersAsTheStringFalse
MeshWeaver.Documentation.Test.AutomationSwitchesReachTheConfigMapGuard ‑ AnUnsetSwitch_IsOmittedFromTheConfigMap
MeshWeaver.Documentation.Test.AutomationSwitchesReachTheConfigMapGuard ‑ EveryEnabledSwitchInTheTemplate_IsClassifiedHere
MeshWeaver.Documentation.Test.PlatformFileReaderGuard ‑ TheBudgetMode_ReadsTheBudget_WarnsAtEightyPercent_AndNeverFailsTheJob(body: "[1,2,3]", withToken: True, expected: "REST budget: /rate_limit answered something unread"···, warns: False)
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

    22 files  ± 0      22 suites  ±0   47m 27s ⏱️ - 4m 59s
10 982 tests +84  10 789 ✅ +87  193 💤 ±0  0 ❌  - 3 
10 995 runs  +84  10 802 ✅ +87  193 💤 ±0  0 ❌  - 3 

Results for commit dda8e28. ± Comparison against base commit 041dde2.

This pull request removes 44 and adds 104 tests. Note that renamed tests count towards both.

   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---, expected: True)
   --- End of inner exception stack trace ---, isDenial: True)
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---
 ---> (Inner Exception #1) MeshWeaver.Messaging.Hub.Test.InfrastructureFaultTest+ProviderException (0x80004005): Failed to connect to 10.42.18.4:5432<---
 ---> (Inner Exception #1) System.ArgumentException: Value does not fall within the expected range.<---
 ---> (Inner Exception #1) System.InvalidOperationException: boom<---
 ---> (Inner Exception #1) System.InvalidOperationException: source B is misconfigured<---
 ---> (Inner Exception #1) System.Net.Sockets.SocketException (0xFFFDFFFF): Name or service not known<---
…
Memex.Portal.Shared.Test.InstanceIdRulesMatchTheRegistryTest ‑ TheSetupHostAgreesWithTheRegistry(candidate: "cdd651a0-2ce2-47d7-9304-4b9e897c7982")
Memex.Portal.Shared.Test.SessionDenialIsAnAnswerTest ‑ OnlyAVerdictReadsAsADenial(shape: "the same verdict nested, as a late denial dispatch"···, failure: System.InvalidOperationException: write failed
 ---> System.UnauthorizedAccessException: Access denied
   --- End of inner exception stack trace ---, isDenial: True)
Memex.Portal.Shared.Test.VersionSelectTest ‑ AMajorPattern_CrossesFromTheOldNotationToTheNew
Memex.Portal.Shared.Test.VersionSelectTest ‑ Stable_NeverSelectsANewNotationBuild
Memex.Portal.Shared.Test.VersionSelectTest ‑ TheNewNotationsEdgeBuild_IsGatedLikeTheOld
Memex.Portal.Shared.Test.VersionSelectTest ‑ TheOldFleetPattern_NeverSelectsTheNewNotation
Memex.Portal.Shared.Test.VersionSelectTest ‑ WideningThePattern_BeforeTheCutOver_ChangesNothing
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall as an aggregate's FIRST member", fault: System.AggregateException: One or more errors occurred. (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.
   --- End of inner exception stack trace ---, expected: True)
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall as an aggregate's SECOND member", fault: System.AggregateException: One or more errors occurred. (The operation has timed out.) (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> System.TimeoutException: The operation has timed out.
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---
, expected: True)
MeshWeaver.Compiler.Pipeline.Test.SourcesWatcherStallBackoffTest ‑ The_production_classifier_recognises_a_stall_through_every_wrapping(because: "a stall nested in an aggregate inside a wrapper", fault: System.InvalidOperationException: outer
 ---> System.AggregateException: One or more errors occurred. (Value does not fall within the expected range.) (Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.)
 ---> System.ArgumentException: Value does not fall within the expected range.
   --- End of inner exception stack trace ---
 ---> (Inner Exception #1) MeshWeaver.Mesh.QueryProviderStalledException: Query provider(s) [pg] did not emit an Initial within the query fan-in's 16s bound for query 'nodeType:NodeType' (user 'system'). The merged Initial gates on EVERY provider, so this query has NO snapshot to answer with — it is reported as unavailable (retryable) rather than left hanging with no error. This is an availability failure, never a permission verdict: a consumer deciding access must fail CLOSED and say it could not establish the answer. Fix the stalled provider; never bump the consumer's timeout.<---

   --- End of inner exception stack trace ---, expected: True)
…

♻️ This comment has been updated with latest results.

rbuergi and others added 2 commits October 4, 2026 08:45
…t a literal branch name

ArmedMergeMustTriggerMainsPushLanesGuard.TheArmLaneArmsOnlyOntoTheRepositoryDefaultBranch
forbids naming the branch literally in this lane. The fetch now names no ref, so the
contents API reads core's default branch (core's, not the caller's, which is what
github.event.repository.default_branch would give on a workflow_call).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@rbuergi

rbuergi commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 79c9c5e: the literal branch name in the gate's fetch is gone. TheArmLaneArmsOnlyOntoTheRepositoryDefaultBranch passes. The fetch now names no ref, so the contents API reads core's default branch. github.event.repository.default_branch would give the caller's branch on a workflow_call, which is the wrong repository for this read. I also merged origin/main.

Still red: NoWorkflowMergesOrArmsAPullRequestWithTheDefaultToken. Local run: Total 11, Failed 1. The gate step sets GH_TOKEN: ${{ github.token }} in a file that runs gh pr merge, and the guard checks the whole file. A minted App token won't fix this as things stand. Measured from orgs/Systemorph/installations:

  • meshweaver-cloud (4220566), the only App whose secrets the callers pass, has no checks permission.
  • The Apps that do have checks are meshweaver-reader (4919171, read) and systemorph-com (4918443, write). The satellites have neither App's secrets: Plugins has only MESHWEAVER_APP_*.

Renaming the env var to GITHUB_TOKEN would only get past the guard's spelling check, so I'm not doing that.

Merge blocker (from this PR's own description): no caller grants checks: read yet. I checked auto-arm.yml on main in Plugins, Education, Reinsurance, SocialMedia, Manufacturing, Crm, FundReporting and Memex: none has checks: or the new triggers, and I found no step-2 PRs. Merging now would make the lane fail at startup in all eight. So this stays a draft. Undrafting would let main's auto-arm lane arm it on ready_for_review.

A maintainer needs to pick one:

  1. Grant meshweaver-cloud the Checks: read permission (an org-level App change that needs approval on each installation). The gate then mints permission-checks: read from the App the callers already pass. That fixes the guard honestly, needs no caller changes and no step 2, and the roster's RETIRING rows go back.
  2. Keep the caller-grant design: open the eight step-2 caller PRs and move the gate's read into a separate reusable workflow file that merges nothing. Both the GitHub-documented resolution of a nested ./ uses: and the need to avoid a literal @main in auto-arm.yml have to be settled first.

🤖 Generated with Claude Code

… token

The gate step passed GITHUB_TOKEN as GH_TOKEN in a file that merges, which
ArmedMergeMustTriggerMainsPushLanesGuard forbids file-wide. It now mints a
meshweaver-cloud installation token with checks/contents/pull-requests: read from
the MESHWEAVER_APP_* secrets every caller already passes. No caller grants
checks: read any more: the workflow drops it, and every auto-arm roster row in
lane-caller-grants.yml is back to {contents: write, pull-requests: write} with no
pending marker (the satellites' real grant). Requires the meshweaver-cloud App to
carry Checks: read; without it the mint fails red and nothing is armed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@rbuergi

rbuergi commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

New precondition. This replaces "every caller grants checks: read" in the description. The maintainer chose option 1. As of cf2191f:

  • The arm gate reads the check runs with a read-only token minted from the meshweaver-cloud App: actions/create-github-app-token@v3, with permission-checks: read, permission-contents: read and permission-pull-requests: read. It uses the MESHWEAVER_APP_* secrets every caller already passes. GITHUB_TOKEN no longer appears anywhere in auto-arm.yml.
  • The workflow drops checks: read. Every auto-arm.yml row in lane-caller-grants.yml is back to {contents: write, pull-requests: write} with no pending marker, which is what the satellites grant today. No caller PRs are needed.
  • I updated the doc paragraph in ReviewFindingsAnswered → "The arm gate" to match.

Merge only once the meshweaver-cloud App (app id 4220566, installation 144517285) carries Checks: read. Before then the mint fails, the lane goes red, and nothing is armed. Check with:
gh api orgs/Systemorph/installations --jq '.installations[]|select(.app_id==4220566)|.permissions.checks'

Local results: ArmedMergeMustTriggerMainsPushLanesGuard Total 11, Failed 0. check-workflow-permission-pairing.py --fleet exits 0, and its --self-test passes 14/14.

🤖 Generated with Claude Code

Arming is a decision (reviewed head, every finding answered), and the control
instance's PR steward (App systemorph-com) already reads both, so it becomes the
one place that arms. auto-arm.yml keeps its name and callers and now only
DISARMS on synchronize (GitHub keeps auto-merge across a push), with a read-back
and no tolerated failure. The read token, the check_run and review-comment
triggers, the arm and the base/comment steps are gone; the lane needs no checks
permission.

Guards: NoWorkflowArmsAutoMerge replaces the per-workflow default-branch checks
(nothing left to arm), and TheAutoMergeLaneDisarmsOnEveryPushAndToleratesNoFailure
pins the disarm. Doc ReviewFindingsAnswered 'The arm gate' states the control
plane's predicate; check-review-answered.py --arm-gate is its reference.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@rbuergi

rbuergi commented Oct 4, 2026

Copy link
Copy Markdown
Contributor Author

Reshaped (ad68d15): arming moves to the control plane. This replaces the precondition in my previous comment. The meshweaver-cloud Checks route is dropped.

  • auto-arm.yml no longer arms. It keeps its file name, so the eight callers need no change. On synchronize it now only disarms: if the pull request is armed it runs gh pr merge --disable-auto, then reads auto_merge back. It has no continue-on-error, because a disarm that fails quietly would let an unreviewed head merge on the reviewed head's arm. These are gone from it: the read token, the check_run and pull_request_review_comment triggers, the base step, the comment step and the arm step. It uses only contents: write and pull-requests: write, so meshweaver-cloud needs no Checks permission.
  • lane-caller-grants.yml: every auto-arm.yml row reads {contents: write, pull-requests: write} with no pending marker.
  • Guards:
    • NoWorkflowArmsAutoMerge replaces the per-workflow default-branch checks, since no workflow arms any more.
    • TheAutoMergeLaneDisarmsOnEveryPushAndToleratesNoFailure pins the disarm.
    • Local runs: guard class Total 9, Failed 0. Against main's arming lane, both new tests fail. Full Documentation.Test suite: 663 / 0.
  • ReviewFindingsAnswered → "The arm gate" now states the predicate the control plane applies. check-review-answered.py --arm-gate is its reference implementation, and its self-test cases are the test vectors.

Precondition: merge only once control-plane arming is live. Once this lands, no workflow arms, so until the PR steward arms, every pull request in the fleet needs a hand-arm. Stays draft until then.

🤖 Generated with Claude Code

rbuergi and others added 2 commits October 7, 2026 11:40
…te's five conditions; no stale 'auto-arm arms' claims

Adapts #6063 to policy copilot-code-review (#6229): the arm-gate doc, the
script comments and the guard message accept a Copilot review of the current
head ahead of an internal-review run, and add condition 5 (required checks
green, policy review-then-suites). Replaces the hard-coded policy dates with
policy ids. AGENTS.md, the pullrequest skill, FleetCiProcess, MergeQueue and
HybridGitHubAzureDevOps no longer say auto-arm.yml arms every non-draft PR.
Names the owed PrArming port as the merge precondition.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@rbuergi
rbuergi marked this pull request as ready for review October 7, 2026 09:43
Copilot AI balanced review requested due to automatic review settings October 7, 2026 09:43
@meshweaver-cloud
meshweaver-cloud Bot enabled auto-merge October 7, 2026 09:44
@rbuergi
rbuergi marked this pull request as draft October 7, 2026 09:44
auto-merge was automatically disabled October 7, 2026 09:44

Pull request was converted to draft

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Disarming remains vulnerable to execution-order and fork-push gaps, and the replacement armer is not yet operationally ready.

Review effort: Balanced
Findings: 2 High severity · 1 Medium severity · 2 Low severity

Open (5)
What changed in this PR

Moves auto-merge arming from GitHub Actions to the control-plane steward, leaving the workflow responsible for disarming after pushes.

Changes:

  • Replaces automatic arming with App-authenticated disarming.
  • Adds guards preventing workflow-based arming.
  • Updates permissions and operational guidance.
File Description
.github/​workflows/​auto-arm.yml Converts the lane to disarm-only behavior.
.github/​lane-caller-grants.yml Removes obsolete checks permissions.
.github/​scripts/​check-review-answered.py Updates arm-gate ownership documentation.
test/​MeshWeaver.Documentation.Test/​ArmedMergeMustTriggerMainsPushLanesGuard.cs Guards the new workflow contract.
src/​MeshWeaver.Documentation/​Data/​Architecture/​ReviewFindingsAnswered.md Documents control-plane arming criteria.
src/​MeshWeaver.Documentation/​Data/​Architecture/​MergeQueue.md Partially updates queue behavior guidance.
src/​MeshWeaver.Documentation/​Data/​Architecture/​HybridGitHubAzureDevOps.md Updates the hybrid-process description.
src/​MeshWeaver.Documentation/​Data/​Architecture/​FleetCiProcess.md Updates fleet arming guidance.
AGENTS.md Revises merge automation instructions.
.claude/​skills/​pullrequest/​SKILL.md Updates pull-request operating guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/auto-arm.yml
Comment thread .github/workflows/auto-arm.yml Outdated
Comment thread .github/workflows/auto-arm.yml
Comment thread src/MeshWeaver.Documentation/Data/Architecture/FleetCiProcess.md
Comment thread src/MeshWeaver.Documentation/Data/Architecture/MergeQueue.md
@systemorph-com systemorph-com Bot added the thread:pr-systemorph-meshweaver-6063-cbfad9 https://memex.systemorph.com/Hosting/Triage/_Thread/pr-systemorph-meshweaver-6063 label Oct 7, 2026
@rbuergi

rbuergi commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Prerequisite: Systemorph/MeshWeaver.Plugins#3088. It ports core #6229's Copilot acceptance (copilot_review_on, checked first, then a real internal-review) into the control plane's PrArming. Without it, PrArming still requires an internal-review run and never arms. Keep this PR a draft until #3088 has MERGED and is deployed on the control instance (with a recycle of the Hosting/Deployment NodeType). Only then should auto-arm.yml become disarm-only. The register note is updated in #6238.

@rbuergi
rbuergi marked this pull request as ready for review October 7, 2026 15:54
@meshweaver-cloud
meshweaver-cloud Bot enabled auto-merge October 7, 2026 15:54
@systemorph-com
systemorph-com Bot disabled auto-merge October 7, 2026 15:56
…ger describe the retired arm lane

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 7, 2026 16:01
@meshweaver-cloud
meshweaver-cloud Bot enabled auto-merge October 7, 2026 16:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new guard currently fails against the workflow syntax and misses an existing workflow-driven arming path.

2 open findings
5 resolved since last review
Previously missed (2)

In code that hasn't changed since last review

Medium severity Guard misses auto-merge invoked by workflow scripts

test/​MeshWeaver.Documentation.Test/​ArmedMergeMustTriggerMainsPushLanesGuard.cs:520

This directory-only text scan already has a false negative: merge-queue-steward.yml invokes .github/scripts/merge-queue-steward.py, whose enqueue method executes both enqueuePullRequest and the enablePullRequestAutoMerge fallback (lines 701 and 707). Therefore NoWorkflowArmsAutoMerge reports no offender even though a workflow can still arm auto-merge. Either include workflow-invoked scripts in the guard or narrow the invariant and explicitly account for the steward.

Low severity Update Copilot auto-arming records to shipped state

src/​MeshWeaver.Documentation/​Data/​Architecture/​ReviewFindingsAnswered.md:1111

This newly added warning contradicts the PR's stated satisfied precondition: Plugins#3088 has merged and the deployed PrArming now accepts Copilot reviews. It also points readers to PolicyNotProse.md:170, which still lists that port as owed. Update both records to the shipped state; otherwise the operational manual says Copilot-only PRs still require manual arming.

🧠 Review effort: Balanced

Comment on lines +556 to +558
var jobCondition = Regex.Match(text, @"\n if: >-\n((?: .*\n)+)");
Assert.True(jobCondition.Success, "auto-arm.yml's job-level `if:` is no longer in the expected block form.");
Assert.Contains("synchronize", jobCondition.Groups[1].Value, StringComparison.Ordinal);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dda8e28: the guard now matches the actual single-line form and asserts the exact predicate github.event.action == 'synchronize'; the class passes (9/9).

Comment on lines +1071 to +1075
**Arming is a decision, so it moved to the control plane** (policy
[`review-then-suites`](../PolicyNotProse)). The control instance's PR steward (MeshWeaver.Plugins
`PrArming`, App `systemorph-com`) already reads every fleet pull request's review state and
answered-findings verdict; it is the one place that arms. **No workflow arms auto-merge any more** —
`ArmedMergeMustTriggerMainsPushLanesGuard.NoWorkflowArmsAutoMerge` fails the build if one does.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in dda8e28: ReviewFindingsAnswered.md and review-answered.yml now say the control plane (PrArming) arms, and auto-arm.yml only disarms on a push.

@systemorph-com
systemorph-com Bot disabled auto-merge October 7, 2026 16:07
…he control plane arms, auto-arm only disarms

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@meshweaver-cloud
meshweaver-cloud Bot enabled auto-merge October 7, 2026 16:40
@systemorph-com
systemorph-com Bot disabled auto-merge October 7, 2026 16:41
@rbuergi
rbuergi merged commit b6d95b4 into main Oct 7, 2026
60 checks passed
@rbuergi
rbuergi deleted the fix/arm-after-review-lane branch October 10, 2026 13:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

thread:pr-systemorph-meshweaver-6063-cbfad9 https://memex.systemorph.com/Hosting/Triage/_Thread/pr-systemorph-meshweaver-6063

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants