Skip to content

A schema id carries the organisation's name and is not a repository name - #160

Merged
HackingGate merged 1 commit into
mainfrom
schema-id-is-not-a-repository-name
Sep 12, 2026
Merged

A schema id carries the organisation's name and is not a repository name#160
HackingGate merged 1 commit into
mainfrom
schema-id-is-not-a-repository-name

Conversation

@HackingGate

Copy link
Copy Markdown
Owner

What was refused

no-private-repo-names extracts a declared private owner written on its own,
with no repository after it: a sentence naming a private organisation discloses
that it exists and who owns it without naming one of its repositories. The
search for it is the owner as a word, and that is one word short.

An organisation that publishes document formats carries its own name in every
id it publishes. The convention is a lowercase organisation name, a dot, the
document's name, then .v and a number -- acme.widget_state.v1, and the
.schema.json file that holds it. The bare-owner search read the first segment
of each of those as the organisation named on its own, so at the text seam a
pull-request body could not quote the id of the schema it was adding, in the
repository where the ids ARE the subject. Measured on one workspace where every
published contract carries the prefix: the author elided the line and pointed at
a committed fixture instead.

What changed

One arm. The bare-owner search now looks at what follows the name it matched: a
schema id continues with one or more dotted segments and then a version
segment, anchored at the end of that match so a version number elsewhere in the
sentence decides nothing about this occurrence. An occurrence that opens a
schema id is not the organisation named on its own; a text whose only
occurrences are schema ids has nothing in it to refuse.

Nothing else moves, and a schema id has no slash in it, so it cannot reach any
of the other forms:

form in the text before after
acme.widget_state.v1 refused passed
acme.widget_state.v1.schema.json refused passed
acme/widget-contracts, bare, declared owner refused refused
https://github.com/acme/widget-contracts refused refused
acme in a sentence refused refused
acme.internal runs the build refused refused

A text carrying an id AND a repository name is still refused, over the second.

The planted cases

Four unit tests over the extractor and one CLI test driving the binary at the
text seam, each way:

  • a_schema_id_is_not_the_organisation_named_on_its_own -- the id and the file
    name that carries it, both clean.
  • a_repository_name_under_a_declared_owner_is_still_a_finding -- one text with
    both shapes; the repository name survives.
  • a_declared_owner_written_on_its_own_is_a_finding and
    a_version_that_is_not_a_version_segment_is_not_a_schema_id -- the controls
    the exemption is measured against.
  • a_schema_id_passes_the_text_seam_and_a_repository_name_does_not -- through
    the binary: exit 0 for the id, exit 1 naming the repository, exit 1 for
    the organisation in a sentence.

docs/REFERENCE.md gains the row and the paragraph that says which half is
decided by what; policy/base/published-text.toml says it on the rule whose
seam it was measured at.

Checks

cargo test (all suites), cargo clippy --all-targets, and
prek run --files over the four changed files: green.

Two notes about the environment this was prepared in, neither a property of this
change. prek at commit-msg hands the message file to every file hook that
did not declare a stage, so shellcheck, actionlint and check-toml lint the
commit message as shell, a workflow and TOML respectively; they were skipped for
the commit. And tests/shim_cli.rs and tests/hook_cli.rs each fail one
editor/harness case when run from inside the pre-push hook while GIT_EDITOR is
set in the surrounding environment; both suites pass on their own and in a full
cargo test.

Answers policy issue 152 in the workspace that measured it: the rule learns to
tell a schema id from a repository name, rather than the doctrine deciding the
ids are private.

https://claude.ai/code/session_01YMvcqzcJEMc8juzt6gDbbJ

The bare-owner arm of no-private-repo-names refused every identifier of the
shape <owner>.<document>.v<N>. An organisation that publishes document formats
writes its own name into every id it publishes, so the search that exists to
catch the organisation named on its own caught the id of a FORMAT instead --
and in the repository where those ids are the subject, no pull-request body
could say which schema it was adding. Measured on one workspace whose whole
contracts directory carries the prefix: the author elided the line and pointed
at a committed fixture instead.

The id is told from the name by what FOLLOWS the owner: one or more dotted
segments and then a version segment, anchored at the end of the match so a
version number later in the sentence decides nothing about this occurrence.
Only the bare arm moves. A schema id has no slash in it, so the owner-and-name
form under a declared owner is refused exactly as before, and so is the
organisation written on its own -- there being no id after the name is the
whole difference, and a text carrying both shapes is still refused over the
second.

A planted case each way: the unit tests over the extractor, and one CLI test
driving the binary at the text seam, where this was measured.

Claude-Session: https://claude.ai/code/session_01YMvcqzcJEMc8juzt6gDbbJ
@coderabbitai

coderabbitai Bot commented Sep 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 26 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: ded6f15c-ff16-48bd-a790-334238e3135e

📥 Commits

Reviewing files that changed from the base of the PR and between 38d27c7 and fd45c9a.

📒 Files selected for processing (4)
  • docs/REFERENCE.md
  • policy/base/published-text.toml
  • src/guard/names.rs
  • tests/text_cli.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.25%. Comparing base (66a14b7) to head (fd45c9a).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #160      +/-   ##
==========================================
+ Coverage   93.23%   93.25%   +0.01%     
==========================================
  Files          38       38              
  Lines       15486    15529      +43     
==========================================
+ Hits        14439    14482      +43     
  Misses       1047     1047              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@HackingGate
HackingGate merged commit e358a95 into main Sep 12, 2026
12 checks passed
@HackingGate
HackingGate deleted the schema-id-is-not-a-repository-name branch September 12, 2026 09:17
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.

2 participants