Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions .github/workflows/release-successor-candidate.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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 }}
Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/release-successor-feed-readiness.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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'
Expand Down
21 changes: 21 additions & 0 deletions docs/roadmaps/utel-release-successor.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
10 changes: 5 additions & 5 deletions scripts/release_successor_journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"}



Expand Down
2 changes: 1 addition & 1 deletion scripts/telemetry-host-published-org-read.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"}

Expand Down
2 changes: 1 addition & 1 deletion src/FS.GG.Coord.Cli/FS.GG.Coord.Cli.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ coherent set cut from corrected source. All three partial sets are recorded in
`registry/dependencies.yml`.</FsggStandingAdvisories>

<PackageReleaseNotes>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)

Expand Down
40 changes: 20 additions & 20 deletions tests/release-successor-candidate/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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",
Expand All @@ -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):
Expand All @@ -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)
Expand Down
Loading
Loading