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
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@
"repodataPackageMatches": [],
"stagedRecipesPr": "https://github.com/conda-forge/staged-recipes/pull/33452",
"stagedRecipesPrState": "OPEN",
"stagedRecipesChecks": "green as of latest GitHub/Azure status check rollup",
"stagedRecipesHeadSha": "bffc5bf1a85389dc695adfd96c87bf2413f4db25",
"stagedRecipesStatusApiState": "success",
"stagedRecipesStatusApiContexts": [
{
"context": "conda-forge-linter",
"state": "success",
"description": "All recipes are excellent."
}
],
"evidenceFile": "conductor/tracks/conda_forge_feedstock_submission_20260524/public_probe_20260703.json",
"result": "No public conda-forge package is available yet as of the 2026-07-03 live probe; staged-recipes PR remains maintainer-review/merge pending."
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
## Phase 4: Publication Evidence

- [~] Task: Verify external publication. Pending conda-forge acceptance.
- [ ] Query public registry after propagation. 2026-06-12 Anaconda API query still returns 404 for `conda-forge/nwau-py`.
- [x] Query public registry after propagation. 2026-07-03 Anaconda API query still returns 404 for `conda-forge/nwau-py`; conda-forge noarch repodata contains no `nwau-py` entries. `1597c33`
- [x] Record immutable URL/API response/checksum.
- [ ] Mark track complete only if publication or accepted-review evidence exists. Publication is not claimed; PR #33452 checks are green at `bffc5bf1a85389dc695adfd96c87bf2413f4db25` and maintainer review/merge remain pending.
- [ ] Mark track complete only if publication or accepted-review evidence exists. Publication is not claimed; PR #33452 remains open at `bffc5bf1a85389dc695adfd96c87bf2413f4db25`; the GitHub status API reports `conda-forge-linter` success and maintainer review/merge remain pending.
- [ ] Task: Conductor - Automated Review and Checkpoint 'Publication Evidence' (Protocol in workflow.md). Pending publication evidence.
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"schemaVersion": 1,
"evidenceType": "conda_forge_publication_probe",
"asOf": "2026-07-03T06:43:53Z",
"package": "nwau-py",
"version": "0.2.2",
"registry": "conda-forge",
"submissionUrl": "https://github.com/conda-forge/staged-recipes/pull/33452",
"status": "submitted_checks_green_pending_conda_forge_review",
"publicationClaimed": false,
"targetVersionVisible": false,
"publicProbes": {
"anacondaApi": {
"url": "https://api.anaconda.org/package/conda-forge/nwau-py",
"httpStatus": 404,
"targetVersionVisible": false
},
"anacondaPage": {
"url": "https://anaconda.org/conda-forge/nwau-py",
"httpStatus": 200,
"targetVersionVisible": false,
"note": "The package-level page route returns HTTP 200 from this environment, but it does not prove the target version. Anaconda API and repodata are authoritative for target-version evidence."
},
"noarchRepodata": {
"url": "https://conda.anaconda.org/conda-forge/noarch/repodata.json",
"httpStatus": 200,
"packageMatches": [],
"targetVersionVisible": false
}
},
"submissionProbe": {
"url": "https://github.com/conda-forge/staged-recipes/pull/33452",
"state": "open",
"merged": false,
"headSha": "bffc5bf1a85389dc695adfd96c87bf2413f4db25",
"headRef": "add-nwau-py-0.2.2",
"headRepository": "edithatogo/staged-recipes",
"baseRef": "main",
"updatedAt": "2026-06-11T13:24:37Z",
"statusApiState": "success",
"statusApiContexts": [
{
"context": "conda-forge-linter",
"state": "success",
"description": "All recipes are excellent."
}
]
},
"claimBoundary": {
"stagedRecipesPrMerged": false,
"feedstockCreated": false,
"publicAnacondaApiVisible": false,
"publicRepodataVisible": false,
"targetVersionPublished": false,
"trackComplete": false,
"archiveEligible": false
},
"nextAction": "Wait for conda-forge maintainer review/merge, then verify the feedstock and public Anaconda API or repodata expose nwau-py 0.2.2 before claiming publication."
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Work this registry one by one using a fail-closed process: discover existing pub

## Current Blocker

Resolved locally and submitted upstream. A conda-forge recipe exists, its source SHA256 matches the published PyPI sdist for `nwau-py==0.2.2`, and a staged-recipes PR is open. Automated lint feedback was addressed and pushed to the PR branch in commit `e6ff7985c94b78471457e446e8fe3abfbe61fa41`. The latest live poll on 2026-06-12 shows PR #33452 open at head `bffc5bf1a85389dc695adfd96c87bf2413f4db25` with conda-forge-linter, GitHub linter, Azure staged-recipes, linux_64, osx_64, win_64, build status, fast-finish, and check-skip checks all green. The remaining blocker is external: conda-forge review, merge, feedstock publication, and public Anaconda propagation.
Resolved locally and submitted upstream. A conda-forge recipe exists, its source SHA256 matches the published PyPI sdist for `nwau-py==0.2.2`, and a staged-recipes PR is open. Automated lint feedback was addressed and pushed to the PR branch in commit `e6ff7985c94b78471457e446e8fe3abfbe61fa41`. The latest live poll on 2026-07-03 shows PR #33452 open and unmerged at head `bffc5bf1a85389dc695adfd96c87bf2413f4db25`; the GitHub status API reports `conda-forge-linter` success. The public Anaconda API still returns 404 and conda-forge noarch repodata contains no `nwau-py` entries. The remaining blocker is external: conda-forge review, merge, feedstock publication, and public Anaconda propagation.

## Preparation Evidence

Expand All @@ -40,7 +40,7 @@ Resolved locally and submitted upstream. A conda-forge recipe exists, its source

- PR: `https://github.com/conda-forge/staged-recipes/pull/33452`
- Fork branch: `edithatogo/staged-recipes:add-nwau-py-0.2.2`
- State: open, current head `bffc5bf1a85389dc695adfd96c87bf2413f4db25`, all visible linter/build/check jobs green, pending review/merge.
- State: open, current head `bffc5bf1a85389dc695adfd96c87bf2413f4db25`, GitHub status API reports `conda-forge-linter` success, pending review/merge.

## Acceptance Criteria

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@
"track": "conda_forge_feedstock_submission_20260524",
"submission_url": "https://github.com/conda-forge/staged-recipes/pull/33452",
"blocker": "conda-forge staged-recipes PR #33452 remains open with green checks. Follow-up public probes on 2026-07-03 still show Anaconda API 404 and no nwau-py entries in conda-forge noarch repodata.",
"publication_claimed": false,
"localReadinessResolved": true,
"preparationEvidence": {
"discovery": "https://api.anaconda.org/package/conda-forge/nwau-py returned package not found.",
Expand All @@ -532,7 +533,16 @@
"repodataPackageMatches": [],
"stagedRecipesPr": "https://github.com/conda-forge/staged-recipes/pull/33452",
"stagedRecipesPrState": "OPEN",
"stagedRecipesChecks": "green as of latest GitHub/Azure status check rollup",
"stagedRecipesHeadSha": "bffc5bf1a85389dc695adfd96c87bf2413f4db25",
"stagedRecipesStatusApiState": "success",
"stagedRecipesStatusApiContexts": [
{
"context": "conda-forge-linter",
"state": "success",
"description": "All recipes are excellent."
}
],
"evidenceFile": "conductor/tracks/conda_forge_feedstock_submission_20260524/public_probe_20260703.json",
"result": "No public conda-forge package is available yet as of the 2026-07-03 live probe; staged-recipes PR remains maintainer-review/merge pending."
}
},
Expand All @@ -545,7 +555,7 @@
"state": "open_checks_green_pending_conda_forge_review",
"lintFeedbackComment": "https://github.com/conda-forge/staged-recipes/pull/33452#issuecomment-4528020623",
"branchUpdate": "GitHub update-branch API accepted on 2026-05-26.",
"latestPoll": "2026-07-03T06:43:53Z: PR #33452 remains OPEN at head bffc5bf1a85389dc695adfd96c87bf2413f4db25; conda-forge-linter, GitHub linter, Azure staged-recipes, linux_64, osx_64, win_64, build status, fast-finish, and check-skip checks all green; Anaconda API still returns 404 and no nwau-py entries appear in conda-forge noarch repodata. Remaining blocker is conda-forge maintainer review/merge and feedstock publication."
"latestPoll": "2026-07-03T06:43:53Z: PR #33452 remains OPEN and unmerged at head bffc5bf1a85389dc695adfd96c87bf2413f4db25; the GitHub status API reports conda-forge-linter success. Anaconda API still returns 404 and no nwau-py entries appear in conda-forge noarch repodata. Remaining blocker is conda-forge maintainer review/merge and feedstock publication."
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion docs/roadmaps/language-registry-external-gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Language registry work is locally prepared where possible. Publication is intent
| Go proxy/pkg.go.dev | Go binding module | Go module proxy and pkg.go.dev expose `v0.1.0` | complete |
| Swift Package Index | `MCHSBind` | `swift build` passed; PackageList issue closed; repo metadata/release fixed; 2026-06-12T12:22:49Z raw PackageList probe now contains `https://github.com/edithatogo/mchs-swift.git`; SPI page probes still return Cloudflare HTTP 403 and API probe returned HTTP 000 from this environment | historical / maintenance-only; public SPI listing/version evidence remains unclaimed |
| Maven Central | `io.github.edithatogo:mchs-jvm-bindings` | JVM module builds locally; Maven publishing metadata and Central Portal namespace/repository wiring are present; successful Publisher API deployment `5fb01ae9-2609-4284-9427-5830e08bcbb5` validated after public key propagation and was published; public Maven metadata exposes `0.1.0`; public JAR SHA-256 is `2f499b78d06317fd9bf2e343542b74043f163f127cd32db4651098f6ac6af49e` | complete |
| conda-forge | `nwau-py` | 2026-07-03 live probe: PR `https://github.com/conda-forge/staged-recipes/pull/33452` remains open at head `bffc5bf1a85389dc695adfd96c87bf2413f4db25`; conda-forge-linter, GitHub linter, Azure staged-recipes, linux_64, osx_64, win_64, build status, fast-finish, and check-skip checks are green; Anaconda API still returns 404 and no nwau-py entries appear in conda-forge noarch repodata | maintainer review, merge, feedstock publication, and public Anaconda propagation |
| conda-forge | `nwau-py` | 2026-07-03 live probe: PR `https://github.com/conda-forge/staged-recipes/pull/33452` remains open and unmerged at head `bffc5bf1a85389dc695adfd96c87bf2413f4db25`; GitHub status API reports `conda-forge-linter` success; Anaconda API still returns 404 and no `nwau-py` entries appear in conda-forge noarch repodata | maintainer review, merge, feedstock publication, and public Anaconda propagation |
| Homebrew | `nwau-py` | personal tap published and verified; `brew info edithatogo/mchs/nwau-py --json=v2` verified stable `0.2.2`, tap head `fa12ed26c1d6a289b40bf59c9bacbb9a5e42f823`, and linked keg `0.2.2` | complete for personal tap; optional Homebrew/core PR/review only if core distribution is required |
| Open VSX / Visual Studio Marketplace | `mchs-tools` | Open VSX API `https://open-vsx.org/api/edithatogo/mchs-tools` returns `edithatogo.mchs-tools` version `0.1.1` after workflow `https://github.com/edithatogo/mchs/actions/runs/27457810800`; `/tmp/mchs-tools-0.1.1.vsix` was manually uploaded through the signed-in Visual Studio Marketplace publisher portal on 2026-06-16T00:24:00+10:00; the public Marketplace Gallery `extensionquery` API now returns public `edithatogo.mchs-tools` version `0.1.1`, last updated `2026-06-15T14:31:27.95Z`, with VSIX SHA-256 `1d20feaa22e66978d5259dfb7b83467ed803a776d3fcb101792f2f164a2807ad` | complete and retained as maintenance-only; no new extension work is planned unless a new evidence-backed need is opened |
| MATLAB File Exchange | `mchs-matlab-interop` | direct public page probe returned HTTP 200 for `https://www.mathworks.com/matlabcentral/fileexchange/184067-mchs-matlab-interop` with title `MCHS MATLAB Interop - File Exchange - MATLAB Central`; MATLAB/Octave runtime validation remains unclaimed because neither runtime is available locally | complete for public File Exchange listing; runtime validation remains unclaimed |
Expand Down
74 changes: 73 additions & 1 deletion scripts/language_registry_external_gate_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,15 @@
"typescript_npm": "https://registry.npmjs.org/@edithatogo%2fmchs-wasm-binding/0.1.0",
"dotnet_nuget": "https://api.nuget.org/v3-flatcontainer/mchs.bindings.dotnet/0.1.0/mchs.bindings.dotnet.0.1.0.nupkg",
"go_module_proxy": "https://proxy.golang.org/github.com/edithatogo/mchs/bindings/go/@v/v0.1.0.info",
"conda_forge": "https://api.anaconda.org/package/conda-forge/nwau-py",
"julia_general": "https://juliahub.com/ui/Packages/General/NationalWeightedActivityUnitWrapper",
}
CONDA_FORGE_PUBLIC_PROBES = {
"anaconda_api": "https://api.anaconda.org/package/conda-forge/nwau-py",
"anaconda_page": "https://anaconda.org/conda-forge/nwau-py",
}
CONDA_FORGE_NOARCH_REPODATA = (
"https://conda.anaconda.org/conda-forge/noarch/repodata.json"
)
CRAN_PUBLIC_PROBES = {
"crandb": "https://crandb.r-pkg.org/nwauR",
"package_page": "https://cran.r-project.org/web/packages/nwauR/index.html",
Expand Down Expand Up @@ -99,6 +105,43 @@ def fetch_post_json(url: str, payload: dict[str, Any]) -> dict[str, Any]:
return {"url": url, "error": type(exc).__name__, "message": str(exc)}


def fetch_conda_noarch_repodata_matches(registry: dict[str, Any]) -> dict[str, Any]:
package = str(registry.get("package") or "")
request = urllib.request.Request(
CONDA_FORGE_NOARCH_REPODATA,
headers={"User-Agent": "mchs-registry-gate-report/1.0"},
)
try:
with urllib.request.urlopen(request, timeout=30) as response: # nosec B310
repodata = json.load(response)
except urllib.error.HTTPError as exc:
body = exc.read(2_000).decode("utf-8", errors="replace")
return {
"url": CONDA_FORGE_NOARCH_REPODATA,
"http_status": exc.code,
"body": body,
"package_matches": [],
}
except Exception as exc:
return {
"url": CONDA_FORGE_NOARCH_REPODATA,
"error": type(exc).__name__,
"message": str(exc),
"package_matches": [],
}

matches = {
filename: payload
for filename, payload in repodata.get("packages", {}).items()
if filename.startswith(f"{package}-")
}
Comment on lines +133 to +137

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Conda channels distribute packages in both the older .tar.bz2 format (under the "packages" key in repodata.json) and the newer .conda format (under the "packages.conda" key). Since conda-forge builds new packages as .conda by default, querying only "packages" will fail to detect the published package. Update the search to scan both keys.

Suggested change
matches = {
filename: payload
for filename, payload in repodata.get("packages", {}).items()
if filename.startswith(f"{package}-")
}
matches = {}
for key in ("packages", "packages.conda"):
for filename, payload in repodata.get(key, {}).items():
if filename.startswith(f"{package}-"):
matches[filename] = payload

return {
"url": CONDA_FORGE_NOARCH_REPODATA,
"http_status": response.status,
"package_matches": matches,
}


def version_visible(registry: dict[str, Any], probe: dict[str, Any]) -> bool:
if probe.get("http_status") != 200:
return False
Expand Down Expand Up @@ -145,6 +188,24 @@ def cran_target_version_visible(
)


def conda_target_version_visible(
registry: dict[str, Any], observation: dict[str, Any]
) -> bool:
if any(
version_visible(registry, probe)
for probe in observation.get("public_probes", {}).values()
):
return True
version = str(registry.get("version") or "")
package = str(registry.get("package") or "")
repodata = observation.get("repodata_probe", {})
matches = repodata.get("package_matches", {})
return any(
payload.get("version") == version and payload.get("name") == package
for payload in matches.values()
)


def classify(registry: dict[str, Any], live: dict[str, Any] | None = None) -> str:
status = str(registry.get("current_status") or "").lower()
blocker = registry.get("blocker")
Expand Down Expand Up @@ -197,6 +258,17 @@ def build_report(contract: dict[str, Any], live: bool) -> dict[str, Any]:
observation["target_version_visible"] = cran_target_version_visible(
registry, observation
)
elif registry_id == "conda_forge":
observation["public_probes"] = {
name: fetch(url)
for name, url in CONDA_FORGE_PUBLIC_PROBES.items()
}
observation["repodata_probe"] = fetch_conda_noarch_repodata_matches(
registry
)
observation["target_version_visible"] = conda_target_version_visible(
registry, observation
)
elif registry_id in PUBLIC_PROBES:
observation["public_probe"] = fetch(PUBLIC_PROBES[registry_id])
observation["target_version_visible"] = version_visible(
Expand Down
67 changes: 67 additions & 0 deletions tests/test_language_registry_external_gate_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,73 @@ def test_cran_registry_contract_remains_submitted_not_published():
assert "d.a.mordaunt@gmail.com" not in json.dumps(registry)


def test_conda_forge_live_probe_requires_target_version_in_public_metadata():
module = _module()
registry = {"id": "conda_forge", "package": "nwau-py", "version": "0.2.2"}

assert (
module.conda_target_version_visible(
registry,
{
"public_probes": {
"anaconda_api": {"http_status": 404, "body": "not found"},
"anaconda_page": {"http_status": 200, "body": "nwau-py"},
},
"repodata_probe": {
"http_status": 200,
"package_matches": {},
},
},
)
is False
)

assert (
module.conda_target_version_visible(
registry,
{
"public_probes": {
"anaconda_api": {"http_status": 404, "body": "not found"},
"anaconda_page": {"http_status": 200, "body": "nwau-py"},
},
"repodata_probe": {
"http_status": 200,
"package_matches": {
"nwau-py-0.2.2-pyhd8ed1ab_0.conda": {
"name": "nwau-py",
"version": "0.2.2",
}
},
},
},
)
is True
)


def test_conda_forge_registry_contract_remains_submitted_not_published():
contract = json.loads(CONTRACT.read_text(encoding="utf-8"))
registry = next(
item for item in contract["registries"] if item["id"] == "conda_forge"
)

assert (
registry["current_status"]
== "submitted_checks_green_pending_conda_forge_review"
)
assert registry["publication_claimed"] is False
assert registry["submission_url"].endswith("/pull/33452")
assert (
registry["preparationEvidence"]["latestPublicProbe20260703"][
"evidenceFile"
]
== (
"conductor/tracks/conda_forge_feedstock_submission_20260524/"
"public_probe_20260703.json"
)
)


def test_vscode_registry_contract_records_marketplace_0_1_1_completion():
contract = json.loads(CONTRACT.read_text(encoding="utf-8"))
registry = next(
Expand Down
Loading