diff --git a/.github/workflows/release-successor-candidate.yml b/.github/workflows/release-successor-candidate.yml index 10b7ff12e..c5add0980 100644 --- a/.github/workflows/release-successor-candidate.yml +++ b/.github/workflows/release-successor-candidate.yml @@ -1,6 +1,6 @@ name: release-successor-candidate -# Source/byte qualification for coherent set 0.112.0 only. This route has no tag, release, +# Source/byte qualification for coherent set 0.113.0 only. This route has no tag, release, # journal, package-feed, OIDC or promotion write. Its retained Actions artifact # is an unpromoted candidate, not a published release or an admission receipt. on: @@ -43,7 +43,7 @@ jobs: test "$(git rev-parse HEAD)" = "$SOURCE_SHA" test "$(git ls-remote origin refs/heads/main | cut -f1)" = "$SOURCE_SHA" version="$(dotnet msbuild src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj -getProperty:Version | tr -d '[:space:]')" - test "$version" = 0.112.0 + test "$version" = 0.113.0 echo "version=$version" >> "$GITHUB_OUTPUT" - name: Verify the stable predecessor and unused package version env: @@ -53,24 +53,24 @@ jobs: run: | set -euo pipefail mkdir -p artifacts/predecessor artifacts/packages - gh release download coherent-set/v0.111.0 --repo "$GITHUB_REPOSITORY" \ + gh release download coherent-set/v0.112.0 --repo "$GITHUB_REPOSITORY" \ --pattern stable-channel.json --dir artifacts/predecessor python3 scripts/release-saga.py predecessor \ --channel artifacts/predecessor/stable-channel.json \ - --release-tag coherent-set/v0.111.0 \ - --tag-source bd60a97a422c8fc8ca0c17b2a9dea4e504b708d2 \ + --release-tag coherent-set/v0.112.0 \ + --tag-source d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5 \ > artifacts/predecessor/identity.json - test "$(jq -r .version artifacts/predecessor/identity.json)" = 0.111.0 + test "$(jq -r .version artifacts/predecessor/identity.json)" = 0.112.0 python3 scripts/check-release-candidate-uniqueness.py \ - --version "$VERSION" --predecessor 0.111.0 + --version "$VERSION" --predecessor 0.112.0 release_status="$(curl --silent --show-error --location -o /dev/null -w '%{http_code}' \ -H "Authorization: Bearer $GH_TOKEN" \ -H 'Accept: application/vnd.github+json' \ - "https://api.github.com/repos/$GITHUB_REPOSITORY/releases/tags/coherent-set/v0.112.0")" + "https://api.github.com/repos/$GITHUB_REPOSITORY/releases/tags/coherent-set/v0.113.0")" test "$release_status" = 404 test -z "$(git ls-remote --tags origin \ - 'refs/tags/coherent-set/v0.112.0' 'refs/tags/kit/v0.112.0' \ - 'refs/tags/drivers/v0.112.0' 'refs/tags/coord-engine/v0.112.0')" + 'refs/tags/coherent-set/v0.113.0' 'refs/tags/kit/v0.113.0' \ + 'refs/tags/drivers/v0.113.0' 'refs/tags/coord-engine/v0.113.0')" - name: Test the telemetry producer and prepare the browser fixture run: | set -euo pipefail @@ -183,7 +183,7 @@ jobs: set -euo pipefail test "$(git ls-remote origin refs/heads/main | cut -f1)" = "$SOURCE_SHA" python3 scripts/check-release-candidate-uniqueness.py \ - --version "$VERSION" --predecessor 0.111.0 + --version "$VERSION" --predecessor 0.112.0 - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: release-successor-candidate-${{ github.sha }}-${{ github.run_id }} diff --git a/.github/workflows/release-successor-feed-readiness.yml b/.github/workflows/release-successor-feed-readiness.yml index 2096dfacf..0f74a2afe 100644 --- a/.github/workflows/release-successor-feed-readiness.yml +++ b/.github/workflows/release-successor-feed-readiness.yml @@ -9,9 +9,9 @@ on: description: Closed read-only observation; no candidate or publication effects type: choice required: true - default: coherent-0112-absence + default: coherent-0113-absence options: - - coherent-0112-absence + - coherent-0113-absence - host-080-org-artifact permissions: @@ -36,7 +36,7 @@ jobs: - name: Verify the exact protected source and offline refusal controls env: SOURCE_SHA: ${{ github.sha }} - OBSERVATION: ${{ inputs.observation || 'coherent-0112-absence' }} + OBSERVATION: ${{ inputs.observation || 'coherent-0113-absence' }} run: | set -euo pipefail test "$GITHUB_REPOSITORY" = FS-GG/.github @@ -47,14 +47,14 @@ jobs: python3 scripts/telemetry-host-published-org-read.py --check-selection python3 tests/release-successor-candidate/run.py python3 tests/telemetry-host-published-org-read/run.py - - name: Observe both feeds for 0.112.0 against published 0.111.0 - if: inputs.observation == 'coherent-0112-absence' || inputs.observation == '' + - name: Observe both feeds for 0.113.0 against published 0.112.0 + if: inputs.observation == 'coherent-0113-absence' || inputs.observation == '' env: GITHUB_TOKEN: ${{ github.token }} run: | set -euo pipefail python3 scripts/check-release-candidate-uniqueness.py \ - --version 0.112.0 --predecessor 0.111.0 + --version 0.113.0 --predecessor 0.112.0 - name: Observe the published Host 0.8 org archive once id: host-org if: inputs.observation == 'host-080-org-artifact' diff --git a/docs/roadmaps/utel-release-successor.md b/docs/roadmaps/utel-release-successor.md index 95d773435..f3be14db8 100644 --- a/docs/roadmaps/utel-release-successor.md +++ b/docs/roadmaps/utel-release-successor.md @@ -2113,3 +2113,24 @@ The closed coherent observation choice is`coherent-0112-absence`; only its liter advance in the shared Host observer. Accepted Host0.8 source/assets/pins, independent read behavior and application-custody acceptance remain unchanged. Source publication updates111 package/tag metadata only after the actual accepted future operation. + +## Selected Claude Code usage coherent113 source window — 2026-10-23 + +Source0.113.0 was composed by [PR4802](https://github.com/FS-GG/.github/pull/4802) (merge`61526e94`) +to carry Claude Code transcript usage capture under parent [Outcome4640](https://github.com/FS-GG/.github/issues/4640). +This window rebinds only the release route. The genuine promoted predecessor is112, immutable +source`d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5`, content +`sha256:1a6f0e3a80f1554819dc8c4185a35ab9fd9894c6b8d6ae97d85f4f3282259adb`, promoted +2026-10-21T17:12:52Z ([release419781177](https://github.com/FS-GG/.github/releases/tag/coherent-set/v0.112.0) +stable-channel asset). Current source selects logical ref +`refs/heads/fsgg/v2/journal/release/coord113-claude-usage-20261023-01` and directory +`state/releases/coord113-claude-usage-20261023-01`. The closed coherent observation choice +becomes`coherent-0113-absence`. + +This is reversible source composition, not namespace allocation, a candidate, a main hold, +publication or installation. Consumed112 and every earlier journal, original attempt and +recovery constant are unchanged. The existing45-minute candidate, exact seven-member archive, +60-minute publisher, Authority-entry ceiling and quota floor contracts are unchanged. Candidate, +publish=false preflight and publish=true each need their own admission on the same immutable +source and archive. Host`claude-local-transcript/1` admission needs a separately released Host +built from at least`61526e94`; this coherent route does not change Host0.8. diff --git a/scripts/release_successor_journal.py b/scripts/release_successor_journal.py index 8631e3b17..773ac5071 100644 --- a/scripts/release_successor_journal.py +++ b/scripts/release_successor_journal.py @@ -36,11 +36,11 @@ # One prospective root-selected source composition; no namespace allocation or effect authority. # Completed110/observer journal and frozen original cuts remain immutable. -CURRENT_RELEASE = {"version": "0.112.0", "predecessor": "0.111.0", - "logicalRef": "refs/heads/fsgg/v2/journal/release/coord112-skill-routing-20261021-01", - "directory": "state/releases/coord112-skill-routing-20261021-01", - "predecessorSource": "bd60a97a422c8fc8ca0c17b2a9dea4e504b708d2", - "predecessorContentId": "sha256:ea0b66a325ef425510a362e189469c5c6e6936880f455898e78520076737298b"} +CURRENT_RELEASE = {"version": "0.113.0", "predecessor": "0.112.0", + "logicalRef": "refs/heads/fsgg/v2/journal/release/coord113-claude-usage-20261023-01", + "directory": "state/releases/coord113-claude-usage-20261023-01", + "predecessorSource": "d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5", + "predecessorContentId": "sha256:1a6f0e3a80f1554819dc8c4185a35ab9fd9894c6b8d6ae97d85f4f3282259adb"} diff --git a/scripts/telemetry-host-published-org-read.py b/scripts/telemetry-host-published-org-read.py index 3957b2250..6f17959f5 100644 --- a/scripts/telemetry-host-published-org-read.py +++ b/scripts/telemetry-host-published-org-read.py @@ -39,7 +39,7 @@ PINS = {"telemetry-host-release.py": "b87002d3192c2cf70d9974a8d7a6b2c3cdca248378c171f04b81519d14c40f7e", "release-saga.py": "24bdfa2a4c1491ecc1ddf24f797a072372fdce14881d413d9301b739dc77501c", "fsgg_feed.py": "f7650429432417af72168c288cdee347b338328848870cb4f2f18d6b62d0733f"} -CHOICES = ("coherent-0112-absence", "host-080-org-artifact") +CHOICES = ("coherent-0113-absence", "host-080-org-artifact") FILES = {PACKAGE, "manifest.json", "publication-journal.json", "local-feed-observation.json", "native-before.json", "native-after.json", "observation.json"} diff --git a/src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj b/src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj index 6614aa090..609b994fd 100644 --- a/src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj +++ b/src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj @@ -131,7 +131,7 @@ coherent set cut from corrected source. All three partial sets are recorded in `registry/dependencies.yml`. 0.113.0 — Add Claude Code transcript usage capture: `telemetry usage collect claude --session-file` and passive `claude-local-transcript/1` observations through the existing provider-usage path. Passive capture retires finished sources and responses, so one association stays within its bounds over days of transcripts; do not roll an association that 0.113.0 has retired back to 0.112.0, which would re-read closed sources. -Carry corrected pnext-item/work-roadmap guidance naming the working Claude route. Codex reading is unchanged apart from closed-source retirement; publication, installed adoption and Host ingestion remain separate; published112 is unchanged. +Board-v2 `migration-prepare` refusals now retain a private typed failure record beside the prepared report (#4812). Carry corrected pnext-item/work-roadmap guidance naming the working Claude route. Codex reading is unchanged apart from closed-source retirement; publication, installed adoption and Host ingestion remain separate; published112 is unchanged. $(FsggStandingAdvisories) diff --git a/tests/release-successor-candidate/run.py b/tests/release-successor-candidate/run.py index f498e8959..317ff9231 100644 --- a/tests/release-successor-candidate/run.py +++ b/tests/release-successor-candidate/run.py @@ -129,22 +129,22 @@ def test_prospective_0104_probe_requires_exact_0102_frontier_on_both_feeds(self) gate.check("0.104.0", "0.102.0", "read-token") def test_selected110_requires_exact109_on_all_six_feed_coordinates(self) -> None: - self.github_read.return_value = ["0.111.0"] - self.nuget_read.return_value = ["0.111.0"] - rows = gate.check("0.112.0", "0.111.0", "inert-token") + self.github_read.return_value = ["0.112.0"] + self.nuget_read.return_value = ["0.112.0"] + rows = gate.check("0.113.0", "0.112.0", "inert-token") self.assertEqual(len(rows), 6) for feed in (self.github_read, self.nuget_read): with self.subTest(feed=feed): - feed.return_value = ["0.111.0", "0.112.0"] + feed.return_value = ["0.112.0", "0.113.0"] with self.assertRaisesRegex(gate.GateError, "already exists"): - gate.check("0.112.0", "0.111.0", "inert-token") - feed.return_value = ["0.111.0"] + gate.check("0.113.0", "0.112.0", "inert-token") + feed.return_value = ["0.112.0"] self.nuget_read.return_value = ["0.108.0"] with self.assertRaisesRegex(gate.GateError, "not predecessor"): - gate.check("0.112.0", "0.111.0", "inert-token") + gate.check("0.113.0", "0.112.0", "inert-token") self.github_read.side_effect = gate.GateError("HTTP 403: occupancy Unknown") with self.assertRaisesRegex(gate.GateError, "occupancy Unknown"): - gate.check("0.112.0", "0.111.0", "inert-token") + gate.check("0.113.0", "0.112.0", "inert-token") def test_an_occupied_version_on_either_feed_refuses(self) -> None: for feed in (self.github_read, self.nuget_read): @@ -240,7 +240,7 @@ def test_prospective_feed_probe_has_only_main_read_permissions_and_no_release_ef self.assertIn('test "$(git ls-remote origin refs/heads/main | cut -f1)" = "$SOURCE_SHA"', workflow) self.assertIn("python3 tests/release-successor-candidate/run.py", workflow) self.assertIn("python3 scripts/check-release-candidate-uniqueness.py", workflow) - self.assertIn("--version 0.112.0 --predecessor 0.111.0", workflow) + self.assertIn("--version 0.113.0 --predecessor 0.112.0", workflow) for forbidden in ( "packages: write", "contents: write", "id-token:", "environment:", "secrets.", "release-successor-publish.py", "release-saga.py", "dotnet pack", @@ -264,9 +264,9 @@ def test_actual_declared_predecessor_command_joins_promoted110_and_current_bindi saga = runpy.run_path(str(ROOT / "scripts/release-saga.py")) workflow = (ROOT / ".github/workflows/release-successor-candidate.yml").read_text() # Genuine promoted110 channel identity; fixture loading makes no native observation. - receipt = {"version":"0.111.0", "sourceSha":"bd60a97a422c8fc8ca0c17b2a9dea4e504b708d2", - "contentId":"sha256:ea0b66a325ef425510a362e189469c5c6e6936880f455898e78520076737298b", - "promotedAt":"2026-10-20T14:26:43.180517Z"} + receipt = {"version":"0.112.0", "sourceSha":"d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5", + "contentId":"sha256:1a6f0e3a80f1554819dc8c4185a35ab9fd9894c6b8d6ae97d85f4f3282259adb", + "promotedAt":"2026-10-21T17:12:52.465057Z"} expected = {"version":CURRENT_RELEASE["predecessor"], "sourceSha":CURRENT_RELEASE["predecessorSource"], "contentId":CURRENT_RELEASE["predecessorContentId"]} def consume(declared, channel): @@ -288,28 +288,28 @@ def consume(declared, channel): with self.assertRaisesRegex(ValueError, "does not match tag source"): consume(workflow.replace("--tag-source "+receipt["sourceSha"], "--tag-source "+old_source), receipt) with self.assertRaisesRegex(ValueError, "does not match release tag"): - consume(workflow.replace("--release-tag coherent-set/v0.111.0", "--release-tag coherent-set/v0.109.0"), receipt) + consume(workflow.replace("--release-tag coherent-set/v0.112.0", "--release-tag coherent-set/v0.110.0"), receipt) with self.assertRaises(AssertionError): consume(workflow, {**receipt,"contentId":"sha256:a3ff6fd1f998e32a750efe25bbb4255c5bd9d9b28ff5b21af441194d44e128ce"}) def test_candidate_binds_the_next_version_and_exact_predecessor(self) -> None: workflow = (ROOT / ".github/workflows/release-successor-candidate.yml").read_text() - self.assertIn('test "$version" = 0.112.0', workflow) - self.assertIn("gh release download coherent-set/v0.111.0", workflow) + self.assertIn('test "$version" = 0.113.0', workflow) + self.assertIn("gh release download coherent-set/v0.112.0", workflow) from release_successor_journal import CURRENT_RELEASE self.assertIn("--tag-source " + CURRENT_RELEASE["predecessorSource"], workflow) - self.assertEqual(workflow.count("--predecessor 0.111.0"), 2) - self.assertIn("--release-tag coherent-set/v0.111.0", workflow) + self.assertEqual(workflow.count("--predecessor 0.112.0"), 2) + self.assertIn("--release-tag coherent-set/v0.112.0", workflow) for namespace in ("coherent-set", "kit", "drivers", "coord-engine"): - self.assertIn(f"refs/tags/{namespace}/v0.112.0", workflow) + self.assertIn(f"refs/tags/{namespace}/v0.113.0", workflow) for project in ("FS.GG.Coord.Cli", "FS.GG.Kit", "FS.GG.Drivers"): self.assertEqual(workflow.count(f"dotnet pack src/{project}/"), 1) initial=workflow.split(' - name: Verify the stable predecessor and unused package version',1)[1].split(' - name: Test the telemetry producer',1)[0] retention=workflow.split(' - name: Refuse a changed main or newly occupied version before retention',1)[1].split(' - uses: actions/upload-artifact',1)[0] - self.assertIn('releases/tags/coherent-set/v0.112.0',initial) + self.assertIn('releases/tags/coherent-set/v0.113.0',initial) self.assertIn('git ls-remote',initial) self.assertIn('refs/heads/main',retention) - self.assertIn('--predecessor 0.111.0',retention) + self.assertIn('--predecessor 0.112.0',retention) self.assertNotIn('releases/tags/',retention) self.assertNotIn('refs/tags/',retention) self.assertIn('timeout-minutes: 45',workflow) diff --git a/tests/release-successor-recovery/run.py b/tests/release-successor-recovery/run.py index f5e3c7ef2..33275b19d 100644 --- a/tests/release-successor-recovery/run.py +++ b/tests/release-successor-recovery/run.py @@ -1627,18 +1627,18 @@ def test_primary_upload_uncertainty_survives_report_failure(self): class SelectedReleaseBindingTests(unittest.TestCase): - def test_current_default_has_112_111_and_selected_skill_identity(self): + def test_current_default_has_113_112_and_selected_claude_usage_identity(self): args = types.SimpleNamespace(recovery_checkpoint=False, repeat_original_nuget_kit_intent=False, recover_original_runtime_intent=False) self.assertEqual(publisher.selected_release_binding(args), - ("0.112.0", "0.111.0", "refs/heads/fsgg/v2/journal/release/coord112-skill-routing-20261021-01")) + ("0.113.0", "0.112.0", "refs/heads/fsgg/v2/journal/release/coord113-claude-usage-20261023-01")) - def test_current_profile_binds_promoted111_and_cannot_claim_old_journals(self): + def test_current_profile_binds_promoted112_and_cannot_claim_old_journals(self): self.assertEqual(set(publisher.CURRENT_RELEASE), {'version','predecessor','logicalRef','directory','predecessorSource','predecessorContentId'}) - self.assertEqual(publisher.CURRENT_RELEASE['predecessorSource'],'bd60a97a422c8fc8ca0c17b2a9dea4e504b708d2') - self.assertEqual(publisher.CURRENT_RELEASE['predecessorContentId'],'sha256:ea0b66a325ef425510a362e189469c5c6e6936880f455898e78520076737298b') - self.assertEqual(publisher.CURRENT_RELEASE['directory'],'state/releases/coord112-skill-routing-20261021-01') - for suffix in ('utel-rel-23','utel-rel-24','utel-rel-25','utel-rel-26','utel-rel-27','coord110-observer-20261020-01','coord111-resource-aware-20261021-01'): + self.assertEqual(publisher.CURRENT_RELEASE['predecessorSource'],'d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5') + self.assertEqual(publisher.CURRENT_RELEASE['predecessorContentId'],'sha256:1a6f0e3a80f1554819dc8c4185a35ab9fd9894c6b8d6ae97d85f4f3282259adb') + self.assertEqual(publisher.CURRENT_RELEASE['directory'],'state/releases/coord113-claude-usage-20261023-01') + for suffix in ('utel-rel-23','utel-rel-24','utel-rel-25','utel-rel-26','utel-rel-27','coord110-observer-20261020-01','coord111-resource-aware-20261021-01','coord112-skill-routing-20261021-01'): authority=MemoryAuthority() with self.subTest(prior=suffix),self.assertRaisesRegex(JournalRefused,'different owner or profile'): ProtectedReleaseJournal(authority,'refs/heads/fsgg/v2/journal/release/'+suffix, @@ -1649,7 +1649,7 @@ def test_current111_cannot_initialize_completed109_journal27(self): authority=MemoryAuthority() journal=ProtectedReleaseJournal(authority,'refs/heads/fsgg/v2/journal/release/utel-rel-27',main_directory=True) authority.calls.clear() - intent={'version':'0.112.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, + intent={'version':'0.113.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, 'candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} with self.assertRaisesRegex(JournalRefused,'different journal identity'): journal.initialize(intent) @@ -1659,7 +1659,7 @@ def test_current111_cannot_initialize_completed110_observer_journal(self): authority=MemoryAuthority() journal=ProtectedReleaseJournal(authority,'refs/heads/fsgg/v2/journal/release/coord110-observer-20261020-01',main_directory=True) authority.calls.clear() - intent={'version':'0.112.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, + intent={'version':'0.113.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, 'candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} with self.assertRaisesRegex(JournalRefused,'different journal identity'): journal.initialize(intent) @@ -1669,7 +1669,17 @@ def test_current112_cannot_initialize_consumed111_journal(self): authority=MemoryAuthority() journal=ProtectedReleaseJournal(authority,'refs/heads/fsgg/v2/journal/release/coord111-resource-aware-20261021-01',main_directory=True) authority.calls.clear() - intent={'version':'0.112.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, + intent={'version':'0.113.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, + 'candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} + with self.assertRaisesRegex(JournalRefused,'different journal identity'): + journal.initialize(intent) + self.assertFalse(any(method in {'post','patch'} for method,_ in authority.calls)) + + def test_current113_cannot_initialize_consumed112_journal(self): + authority=MemoryAuthority() + journal=ProtectedReleaseJournal(authority,'refs/heads/fsgg/v2/journal/release/coord112-skill-routing-20261021-01',main_directory=True) + authority.calls.clear() + intent={'version':'0.113.0','sourceSha':'b'*40,'contentId':'sha256:'+'b'*64, 'candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} with self.assertRaisesRegex(JournalRefused,'different journal identity'): journal.initialize(intent) @@ -2451,7 +2461,7 @@ def test_precredential_workflow_order_and_candidate_binding(self): self.assertLess(fence,workflow.index(name)) self.assertNotIn('disposition_json:',workflow) candidate = (ROOT/'.github/workflows/release-successor-candidate.yml').read_text() - self.assertIn('test "$version" = 0.112.0',candidate) + self.assertIn('test "$version" = 0.113.0',candidate) self.assertNotIn('-p:Version=',candidate) self.assertIn('name: release-successor-candidate-${{ github.sha }}-${{ github.run_id }}',candidate) self.assertIn('Separate evidence: never add a member to the exact seven-member publisher archive.',candidate) @@ -2462,8 +2472,8 @@ class LiteralForwardControls(SuspensionFixture): def context(self): if not hasattr(self,'_forward_base'):self._forward_base=copy.deepcopy(self.authority) self.authority=copy.deepcopy(self._forward_base) - self.install();self.authority.logical_ref=publisher.CURRENT_RELEASE['logicalRef'];self.authority.directory_suffix='coord112-skill-routing-20261021-01';self.authority.calls.clear() - candidate=manifest();candidate['descriptor'].update(version='0.112.0',previousStableVersion='0.111.0') + self.install();self.authority.logical_ref=publisher.CURRENT_RELEASE['logicalRef'];self.authority.directory_suffix='coord113-claude-usage-20261023-01';self.authority.calls.clear() + candidate=manifest();candidate['descriptor'].update(version='0.113.0',previousStableVersion='0.112.0') candidate['contentId']='sha256:'+hashlib.sha256(json.dumps(candidate['descriptor'],sort_keys=True,separators=(',',':')).encode()).hexdigest() counted=publisher.CountedAuthorityAPI(self.authority,ceiling=1500,quota_floor=1800);counted.admit_quota() shared=self.mod.ReleaseSuspension(counted);rows=report();native=MemoryPublisher() @@ -2480,7 +2490,7 @@ def visibility(effect): if observation.state=='matched' and observation.observed_digest==effect.target_digest:return 'potential' raise publisher.Refused('inert pending witness '+observation.state) provider.ordinary_visibility=visibility - intent={'contentId':candidate['contentId'],'sourceSha':'b'*40,'version':'0.112.0','candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} + intent={'contentId':candidate['contentId'],'sourceSha':'b'*40,'version':'0.113.0','candidateArchiveSha256':'c'*64,'operator':'EHotwagner'} publisher.prepare_release_journal(journal,counted,admission,provider,native,candidate,intent,'b'*40,'b'*40,False,lambda:None) journal.capture();ticks=[0];sleeps=[] def sleep(seconds):sleeps.append(seconds);ticks[0]+=seconds @@ -2548,7 +2558,7 @@ def get(path): if '/actions/runs/' in path:row['status']='cancelled' return row native.get=get - elif mode=='suspension':self.add_file('state/releases/coord112-skill-routing-20261021-01/release-state.json',canonical(journal._observed.state)+b' ') + elif mode=='suspension':self.add_file('state/releases/coord113-claude-usage-20261023-01/release-state.json',canonical(journal._observed.state)+b' ') else:next(iter(self.authority.controls.values()))['enforcement']='disabled' with self.assertRaises(RuntimeError):run(sleep=sleep) self.assertEqual(provider.dispatched,['tag']);self.assertEqual(sleeps,[5]) @@ -3559,20 +3569,20 @@ def prepare_caller(self, *, history=0, delays=0, target='channel-asset', ceiling self.add_file('state/releases/utel-rel-27/release-head.txt',self.promoted109_head) # Synthetic completed110 sibling uses the genuine promoted predecessor identity. # Fixture Git bytes/head remain inert; native completion is independently read. - self.promoted110_fixture=canonical({'schema':self.mod.SCHEMA,'version':'0.111.0', - 'sourceSha':'bd60a97a422c8fc8ca0c17b2a9dea4e504b708d2', - 'contentId':'sha256:ea0b66a325ef425510a362e189469c5c6e6936880f455898e78520076737298b', + self.promoted110_fixture=canonical({'schema':self.mod.SCHEMA,'version':'0.112.0', + 'sourceSha':'d5af6a987e915bd0a1b572bcc09ad0d4b2e798b5', + 'contentId':'sha256:1a6f0e3a80f1554819dc8c4185a35ab9fd9894c6b8d6ae97d85f4f3282259adb', 'candidateArchiveSha256':'0'*64,'operator':'EHotwagner','generation':33, 'effects':{effect.identity:'verified' for effect in ordered_effects(manifest())}}) self.promoted110_head=b'0000000000000000000000000000000000000000\n' self.add_file('state/releases/coord110-observer-20261020-01/release-state.json',self.promoted110_fixture) self.add_file('state/releases/coord110-observer-20261020-01/release-head.txt',self.promoted110_head) - self.authority.directory_suffix='coord112-skill-routing-20261021-01';self.authority.logical_ref=publisher.CURRENT_RELEASE['logicalRef'] + self.authority.directory_suffix='coord113-claude-usage-20261023-01';self.authority.logical_ref=publisher.CURRENT_RELEASE['logicalRef'] for n in range(history):self.add_file('state/ordinary/cold-history.json',canonical({'generation':n})) - self.native=Literal104ProviderFixture(self.root,None,version="0.112.0") + self.native=Literal104ProviderFixture(self.root,None,version="0.113.0") stream=io.BytesIO() with zipfile.ZipFile(stream,'w') as archive: - for name in [*(f'{package}.0.112.0.nupkg' for package in PACKAGES), + for name in [*(f'{package}.0.113.0.nupkg' for package in PACKAGES), 'release-manifest.json','previous-stable-channel.json', 'standalone-telemetry-evidence.json','standalone-telemetry-runtime-evidence.json']: archive.writestr(name,(self.root/name).read_bytes()) @@ -3609,7 +3619,7 @@ def get(path,_original_get=original): if '/releases?' in path:return [] if hidden=='promote' and '/releases/tags/' in path:value['draft']=True if hidden and '/assets?per_page=100' in path: - name={**{f'archive-asset:{package}':f'{package}.0.112.0.nupkg' for package in PACKAGES}, + name={**{f'archive-asset:{package}':f'{package}.0.113.0.nupkg' for package in PACKAGES}, 'qualification-asset:evidence':'standalone-telemetry-evidence.json', 'qualification-asset:runtime':'standalone-telemetry-runtime-evidence.json', 'channel-asset':'stable-channel.json','manifest-asset':'release-manifest.json'}.get(hidden) @@ -3679,7 +3689,7 @@ def process(argv,**kwargs): return types.SimpleNamespace(returncode=0) if len(argv)>1 and argv[1].endswith('check-release-candidate-uniqueness.py'): self.local_ports.append('uniqueness-external-port') - self.assertEqual(argv[2:],['--version','0.112.0','--predecessor','0.111.0']) + self.assertEqual(argv[2:],['--version','0.113.0','--predecessor','0.112.0']) self.assertFalse(self.native.feeds);self.assertIsNone(self.native.release) return types.SimpleNamespace(returncode=0) self.local_ports.append('inert-nuget-send' if argv[:3]==['dotnet','nuget','push'] else 'saga:'+argv[2]) @@ -3876,7 +3886,7 @@ def get(path): return row self.native.get=get elif mode=='protection':next(iter(self.authority.controls.values()))['enforcement']='disabled' - else:self.external_file('state/releases/coord112-skill-routing-20261021-01/release-state.json',canonical(self.rows['lastObservedJournal'])+b' ') + else:self.external_file('state/releases/coord113-claude-usage-20261023-01/release-state.json',canonical(self.rows['lastObservedJournal'])+b' ') self.on_sleep=change with self.assertRaises(RuntimeError):self.invoke_caller() self.assertEqual(self.dispatches,['tag']) @@ -3970,7 +3980,7 @@ def prepare(effect): name='release-state.json' if mode=='state' else 'release-head.txt' expected=self.providers[0]._ordinary_expected_journal raw=expected[1]+b' ' if mode=='state' else ('e'*40+'\n').encode() - self.external_file('state/releases/coord112-skill-routing-20261021-01/'+name,raw) + self.external_file('state/releases/coord113-claude-usage-20261023-01/'+name,raw) self.on_prepare=prepare with self.assertRaises(RuntimeError):self.invoke_caller() self.assertIsNone(self.native.tag);self.assertEqual(self.publisher_ports.count('post'),0) diff --git a/tests/telemetry-host-published-org-read/run.py b/tests/telemetry-host-published-org-read/run.py index bf5a84a53..e0bfc3bff 100644 --- a/tests/telemetry-host-published-org-read/run.py +++ b/tests/telemetry-host-published-org-read/run.py @@ -24,11 +24,11 @@ def workflow_contract(text): - required = ["default: coherent-0112-absence", "- coherent-0112-absence", "- host-080-org-artifact", + required = ["default: coherent-0113-absence", "- coherent-0113-absence", "- host-080-org-artifact", "contents: read\n packages: read", "cancel-in-progress: false", "timeout-minutes: 5", "persist-credentials: false", "python3 scripts/telemetry-host-published-org-read.py --check-selection", "python3 tests/release-successor-candidate/run.py", "python3 tests/telemetry-host-published-org-read/run.py", - "if: inputs.observation == 'coherent-0112-absence' || inputs.observation == ''", + "if: inputs.observation == 'coherent-0113-absence' || inputs.observation == ''", "if: inputs.observation == 'host-080-org-artifact'", "if: inputs.observation == 'host-080-org-artifact' && steps.host-org.outcome == 'success'", "name: telemetry-host080-org-read-${{ github.sha }}-${{ github.run_id }}", @@ -43,7 +43,7 @@ def workflow_contract(text): if forbidden in text: raise ValueError("workflow effect or bypass") default, host = text.split(" - name: Observe the published Host 0.8 org archive once", 1) - if "upload-artifact" in default or "--version 0.112.0 --predecessor 0.111.0" not in default: + if "upload-artifact" in default or "--version 0.113.0 --predecessor 0.112.0" not in default: raise ValueError("default coherent branch changed") if text.index("--check-selection") > text.index("python3 tests/"): raise ValueError("selection ordering") @@ -231,7 +231,7 @@ def test_strict_metadata_and_source_pin(self): def test_actual_workflow_and_causal_mutations(self): text=(ROOT/'.github/workflows/release-successor-feed-readiness.yml').read_text();workflow_contract(text) - replacements=[('packages: read','packages: write'),('default: coherent-0112-absence','default: host-080-org-artifact'), + replacements=[('packages: read','packages: write'),('default: coherent-0113-absence','default: host-080-org-artifact'), ('--check-selection','--unchecked'),(" && steps.host-org.outcome == 'success'",''), ('if-no-files-found: error','if-no-files-found: warn'),('tests/telemetry-host-published-org-read/run.py','other.py'), ("if: inputs.observation == 'host-080-org-artifact'\n",'if: always()\n')]