Skip to content

feat(profiles): approve source origins for Microsoft, Mistral AI, xAI, and Cohere - #445

Merged
abdeslam-menacere merged 1 commit into
mainfrom
abdeslam-menacere-approve-long-tail-source-origins
Aug 27, 2026
Merged

feat(profiles): approve source origins for Microsoft, Mistral AI, xAI, and Cohere#445
abdeslam-menacere merged 1 commit into
mainfrom
abdeslam-menacere-approve-long-tail-source-origins

Conversation

@abdeslam-menacere

@abdeslam-menacere abdeslam-menacere commented Aug 27, 2026

Copy link
Copy Markdown
Owner

Approves source origins for four long-tail creators — Microsoft, Mistral AI, xAI, Cohere — so that a later data refresh can cite them. Closes #437.

This populates nothing. The /tree/ page will still render "No non-featured creators in the reviewed catalog." after this merges, correctly. It unblocks the refresh that comes next.

What changed

Five files, additions only, all under a new tools/updater/profiles/origins/ directory:

file what it approves
microsoft.json microsoft.ai, www.microsoft.com (bounded to /en-us/research/blog/)
mistral-ai.json mistral.ai, docs.mistral.ai
xai.json x.ai, docs.x.ai
cohere.json cohere.com, docs.cohere.com
README.md why the directory exists, and what was deferred

Trusted origin union: 16 → 24. The two huggingface.co entries add no new origin; they bound link-following.

Why a subdirectory

The placement is the design, and it is load-bearing. Three consumers read tools/updater/profiles/, and they enumerate it differently:

consumer enumeration sees origins/?
gate-source-approval.mjscatalogAnchor() git ls-tree -r (recursive) yes — this is what makes the change work
gate-evidence.mjs:165 readdirSync, skips non-files no
profiles.py:364_reviewed_profile_paths() iterdir(), skips non-files no

So the origins are visible to the trust anchor and invisible to the reviewed-creator sets. A top-level microsoft.json would instead break test_profiles.py's EXPECTED_CREATORS and promote Microsoft to the 2-of-3 pilot review bar, which #437 places explicitly out of scope. The precedent already exists: profiles/generic/long-tail.json lives in a subdirectory for the same reason.

QA proved the skip is load-bearing rather than incidental by hoisting origins/microsoft.json to the top level: discovery count went 4 → 5, and load_profile_library then refused with ProfileError - microsoft.json: missing required field 'creator'. The worst-case layout mistake fails closed rather than silently promoting a creator.

Gate verdicts

Both gates ran against b57a729, read issue text and git diff only, and never saw the developer's summary or session. Neither reviewed its own work.

gate verdict record
review PASS comment 5445591330
qa PASS comment 5445754879, addendum

drydock is not installed in this environment, so no machine gate receipt exists and none has been hand-written. The issue comments are the authoritative record.

⚠️ The required check passes without executing anything

Correction, made after this PR was opened. An earlier revision of this description claimed CI would run nothing at all for this change. That was wrong, and the error was mine: I enumerated web-ci.yml and skills-ci.yml, reasoned from those two, and never listed the full workflow set. updater-tests.yml exists, triggers on tools/updater/**, and is running the pytest suite on this PR against Python 3.11 and 3.13. Leaving that claim standing would have understated the coverage a reviewer actually has.

The accurate position is narrower, and still worth reading before trusting the checks:

workflow runs here? why
web-ci skips predicate ^(web/|\.github/workflows/web-ci\.yml$)and it is the only required check on main
skills-ci skips predicate ^(\.github/skills/|\.github/scripts/|\.github/workflows/skills-ci\.yml$|web/src/data/)
updater-tests runs paths: tools/updater/** — the Python suite, on 3.11 and 3.13

So the Python half is covered by CI. Two real gaps remain:

  1. The required check is satisfied vacuously. web-ci will go green having executed nothing for this change, so branch protection is not evidence here.
  2. The node gate suite is not run at all. gates.test.mjs is where gate-source-approval.mjs — the script this change actually depends on — is exercised, and skills-ci skips it. skills-ci.yml documents this against itself at lines 110–117: "a pull request confined to that directory skips gates the change would have failed. A green skip records that the gates did not run, never that they would have passed. Do not read one as coverage."

The node gate results and the web result below were therefore run by hand, because nothing in CI runs them for this change. The pytest figures are reproduced by updater-tests on this PR.

Real output

Run against main + this branch merged, re-run after main advanced (see below):

node --test gates.test.mjs        -> tests 149, pass 149, fail 0, exit 0
check-skill-doc-test-counts.mjs   -> OK, 8 markdown file(s), exit 0
tools/updater: python -m pytest   -> 1095 passed, 2 skipped, 3 deselected, exit 0
web: npm.cmd run validate         -> 24 files, 603/603 passed, astro 0 errors, exit 0

The 3 deselected are test_live_publication.py (2) and test_network_provider.py (1), excluded by pre-existing pyproject.toml:65 config (-m 'not network and not live') because they perform real egress. Not hidden coverage.

npm run validate was run against the earlier merge base. git diff origin/main HEAD -- web/ is empty — this branch changes no file under web/ — so main's own CI result carries unchanged.

Mutation probes (QA) — every one tripped

probe expected observed
delete origins/ from the merge union shrinks 24 → 16, 8 accepts → 16 failures, exit 1
8 accept bundles at the pre-change anchor all refused 8/8 exit 1
14 unapproved origins post-change all refused 14/14 exit 1 — incl. Azure, learn.microsoft.com, subdomain squat, scheme swap, userinfo spoof x.ai@evil…
promote any of the four to pilot must not still long-tail; openai control exits 0, so the probe is not vacuous

main moved twice under this branch

Both gate verdicts bind to b57a729, which is unchanged, so they still hold. But the merge target moved from a0528110556ec729acbda, and two of those commits touch machinery this change depends on. Rather than carry a stale result forward, everything was re-measured against the current tip:

Deferred rather than guessed

  • DeepSeekapi-docs.deepseek.com unreachable at verification time, a connection failure rather than a 4xx, so absence of evidence was not recorded as evidence of absence.
  • Alibaba / Qwen — the creator entity is genuinely unresolved.
  • Azure and learn.microsoft.com — deliberately withheld. Microsoft is simultaneously a creator (Phi, MAI), a serving platform (Azure), and a product vendor (Copilot); collapsing those would violate the entity-boundary rule. github.com stays trusted as code hosting only, not as Microsoft's announcement channel.
  • Two conflicts recorded rather than smoothed: x.ai now self-describes as "SpaceXAI LLC" (verified against the live <title> and og:title), and huggingface.co/CohereLabs is isVerified: false, so it was declined.

Known gaps, disclosed

  1. No committed test validates the content of origins/*.json. Set membership is guarded — test_profiles.py:35 asserts EXPECTED_CREATORS against the real directory and fails on a leak (proven: 6 errors under mutation, clean on revert). But the new urls, trust_notes and allowed_paths are unchecked by any suite. A future edit adding azure.microsoft.com would be caught only by human review.
  2. allowed_paths is advisory at this gate. Trust attaches at scheme://host; nothing in tools/updater/src/ parses these documents. Disclosed in the README rather than implied to be enforced.
  3. catalogAnchor swallows parse errors with continue. Pre-existing and fails closed, but newly load-bearing now that a second directory feeds it.
  4. cohere-docs and mistral-docs record a url outside their own allowed_paths. Investigated and benignmeta.json and google-deepmind.json already do the same; it is the established "root entry point, link-following bounded to checked subsections" convention.

Merge

This is outside ADR 0003's qualifying classgate-scope.mjs reports all five files outOfClass, "passed": false, exit 1, so it cannot auto-merge and must not. Auto-merge has deliberately not been enabled.

The merge is a human's. The required check (web-ci) will pass without executing anything for this change, so please weigh the hand-run node-gate output above and the updater-tests result rather than the green tick alone.

Adds tools/updater/profiles/origins/, a reviewed catalogue of human-approved
publication origins for creators that have no dedicated profile. Microsoft,
Mistral AI, SpaceXAI (x.ai) and Cohere are in the first batch; DeepSeek and
Alibaba/Qwen are deferred with their reasons recorded.

gate-source-approval.mjs refuses a citation to any origin the committed dataset
and the profile catalogues do not already stand behind, and no panel vote
overrides it, so approving a new host is a human act by design. These documents
are that act. They approve origins only: no dataset JSON changes here, and
populating the creators stays a separate refresh run.

The documents join neither reviewed set. _reviewed_profile_paths skips
directories, so load_profile_library does not see origins/ any more than it sees
generic/. A creator here is therefore not promoted to a pilot creator and stays
on the unanimous 3-of-3 long-tail bar.

Microsoft is scoped to Microsoft-as-creator: the Phi family on the Microsoft
Research blog and the MAI series on microsoft.ai. azure.microsoft.com and
learn.microsoft.com are deliberately not approved, because Azure serves other
creators' models and approving those origins invites exactly the collapse of
creator into serving platform this repository forbids.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Approve source origins for long-tail creators so the Others branch can be populated

1 participant