Skip to content

Support and audit the csharp+python repo shape (#339) - #343

Merged
ptr727 merged 2 commits into
developfrom
support-csharp-python-shape-339
Jul 17, 2026
Merged

Support and audit the csharp+python repo shape (#339)#343
ptr727 merged 2 commits into
developfrom
support-csharp-python-shape-339

Conversation

@ptr727

@ptr727 ptr727 commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Fixes #339. Registers the fleet's first mixed-language shape (PlexCleaner: a .NET console app plus a stdlib-only Python tooling subtree) and codifies how the csharp and python baselines coexist. Reference implementation: ptr727/PlexCleaner#855.

Per the issue, this is not a new polyglot type - a mixed repo is expressed as types: ["csharp","console","docker","python"] and the audit runs the union of the per-type checks. The work is: register the shape, codify the coexistence rules, add a matrix row.

Three decisions (settled with the owner before writing)

  1. Two python profiles, one type, split by a third-party runtime import. PROJECT = a PEP 621 uv project with runtime deps + committed LF-pinned uv.lock (the existing Financial-Modeling shape). SCRIPTS = stdlib-only utility scripts embedded in a non-Python repo, run via uvx, no lockfile, pyproject.toml carrying only [tool.ruff]/[tool.mypy]. Detected structurally from pyproject.toml.
  2. Tool-version pinning for SCRIPTS is CI-only. CI pins exact versions in the uvx command (uvx ruff@X, bumpable there); tasks/README run latest - a deliberate CI-vs-local gap so local never silently falls behind. PROJECT keeps pinning through uv.lock + uv sync --frozen (unchanged).
  3. Coverage N/A for SCRIPTS. python.coverage.codecov is N/A for a lint/type-only subtree (no pytest); codecov.yml presence stays required by any co-present type with tests (the C# side here).

Changes

File Change
registry/repos.json PlexCleaner types += python; driftNote records the SCRIPTS subtree + which checks go N/A
spec/project-types.json python type: profileNote + new python.profile.detect; SCRIPTS-profile N/A wording on pyright/coverage/uvlock; new python.scripts.uvx check
CODESTYLE.md "Two profiles" paragraph (project vs scripts: uvx, tool-config-only pyproject, mypy, CI-pinned/local-latest, .py on repo EOL default, coverage N/A)
README.md ## Rules Python bullet names the type-checker choice; new "If Both C# and Python" both-apply subsection
reports/conformance-matrix.md csharp + python shape row (PlexCleaner)
cspell.json bumpable, stdlib, uvx

Issue items mapped

  • (1) line endings - CODESTYLE "Scripts" bullet states .py/.toml follow the repo CRLF default (only a shebang-executed script is LF-pinned), so nobody "fixes" .py to LF; recurring.eol already covers the general rule.
  • (2) uvx-vs-uv-project - python.profile.detect + CODESTYLE "Two profiles".
  • (3) CI-only pinning - python.scripts.uvx + CODESTYLE.
  • (4) coverage - python.coverage.codecov N/A wording.
  • (5) tasks.json union - confirmed, no change needed: spec/files.json already carries separate csharp and python .vscode/tasks.json references, so a mixed repo satisfies both by union (that is the intended audit behavior).
  • (6) docs both-apply - README "If Both C# and Python" + CODESTYLE "Two profiles".

Validation

  • python3 spec/validate.py -> OK (21 cataloged, 0 backlog).
  • markdownlint + editorconfig-checker clean on changed files; CI-scoped cspell (README + HISTORY) clean.

Related: #306 (closed - source-only Python adaptation gaps), #310 (open - the conformance-matrix row here is a not-tested entry pending that issue's cold-start self-test).

🤖 Generated with Claude Code

PlexCleaner is the fleet's first csharp+python repo (a .NET console app
plus a stdlib-only Python tooling subtree, RegressionTests/). This
registers the shape and codifies how the csharp and python baselines
coexist, per three decisions settled with the owner.

Decisions (settled up front):
1. The two python profiles are one type, split by a third-party runtime
   import: PROJECT (uv project + committed LF-pinned uv.lock, the
   existing Financial-Modeling shape) vs SCRIPTS (stdlib-only, uvx, no
   lock, pyproject carries only [tool.ruff]/[tool.mypy]).
2. Tool-version pinning for the SCRIPTS profile: CI pins exact versions
   in the uvx command (bumpable there), tasks/README run latest - a
   deliberate CI-vs-local gap. PROJECT keeps pinning via uv.lock +
   --frozen.
3. Coverage: python.coverage.codecov is N/A for a SCRIPTS subtree (no
   pytest); codecov.yml presence stays required by any co-present type
   with tests (csharp here).

Changes:
- registry/repos.json: PlexCleaner types += python; driftNote records
  the SCRIPTS subtree and the N/A checks.
- spec/project-types.json: python type gains a profileNote and a
  python.profile.detect check; pyright/coverage/uvlock checks carry
  explicit SCRIPTS-profile N/A wording; new python.scripts.uvx check
  for the uvx + CI-pinned-versions rule.
- CODESTYLE.md: "Two profiles" paragraph documenting the project vs
  scripts split (uvx, tool-config-only pyproject, mypy checker,
  CI-pinned/local-latest, .py on the repo EOL default, coverage N/A).
- README.md ## Rules: Python bullet names the type-checker choice; new
  "If Both C# and Python" subsection for the both-apply story.
- reports/conformance-matrix.md: csharp+python shape row (PlexCleaner).
- cspell.json: bumpable, stdlib, uvx.

No change needed for the tasks.json union (item 5): spec/files.json
already carries separate csharp and python .vscode/tasks.json
references, so a mixed repo satisfies both by union.

Validated: spec/validate.py passes (21 cataloged), markdownlint +
editorconfig-checker clean, CI-scoped cspell (README+HISTORY) clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 17, 2026 23:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Registers and documents the fleet's first mixed C# + Python repository shape (a .NET console app plus a stdlib-only Python tooling subtree), and updates the audit/spec guidance so the csharp and python baselines can coexist as a union of checks.

Changes:

  • Extend the python type definition to describe two structurally detected profiles (PROJECT vs SCRIPTS), including new/updated N/A expectations (coverage, uv.lock pinning, pyright vs mypy).
  • Register PlexCleaner as types: ["csharp","console","docker","python"] and add the new mixed-language row to the conformance matrix.
  • Update top-level docs/spelling config to reflect the mixed-language rules and new terminology.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
spec/project-types.json Adds python profile concept + new/updated checks (scripts vs project behavior).
CODESTYLE.md Documents how Python “project” vs “scripts” profiles behave in mixed repos.
README.md Updates Rules index to cover Python type-checker choice and “both C# and Python” guidance.
registry/repos.json Registers PlexCleaner as mixed-language and records the scripts-subtree drift note.
reports/conformance-matrix.md Adds the csharp + python supported shape row (PlexCleaner).
cspell.json Adds new terms used by the docs/spec (bumpable/stdlib/uvx).

Comment thread CODESTYLE.md Outdated
Comment thread README.md Outdated
Comment thread spec/project-types.json Outdated
…e (Copilot #343)

The profile is detected structurally from pyproject.toml (metadata +
uv.lock presence), not by inspecting imports - CODESTYLE and the
profileNote now say the third-party-dependency question is *detected
structurally* (python.profile.detect) rather than calling an "import"
the discriminator. The README Python bullet no longer ties pyright to
uv-project and mypy to scripts (a uv project can run mypy-in-CI, as
Financial-Modeling does); it now names the checker choice
profile-independently.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 17, 2026 23:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (2)

spec/project-types.json:36

  • The profile discriminator text is currently too narrow: it implies the PROJECT profile requires runtime dependencies (and the note's shorthand implies uv.lock), but a PEP 621 project can legitimately have no runtime deps and may be non-uv. To avoid misclassifying a project as SCRIPTS, describe the discriminator as presence of [project]/[build-system] (and optionally uv.lock), not dependencies.
            "profileNote": "Two structurally-detected profiles share this type (CODESTYLE.md Python 'Two profiles'). PROJECT: the Python has third-party runtime dependencies or is the repo's deliverable - a PEP 621 uv project (pyproject [project]+deps+[build-system], committed uv.lock, uv sync --frozen + uv run in CI); Financial-Modeling is the reference. SCRIPTS: stdlib-only utility scripts embedded in a non-Python repo (a csharp+python repo like PlexCleaner#855) - run with uvx, no uv.lock, no uv project, pyproject carries only [tool.ruff]/[tool.mypy] config. The two differ by whether the Python has third-party runtime dependencies, which the audit detects structurally from pyproject.toml (see python.profile.detect) rather than by inspecting imports: [project]+deps/[build-system] + uv.lock -> PROJECT; tool-config-only, no [project]/[build-system], no uv.lock -> SCRIPTS. The profile changes which checks apply: see python.profile.detect and the per-check N/A notes.",
            "checks": [
                { "id": "python.profile.detect", "verdict": "letter", "assert": "The profile is read from pyproject.toml: a [project] table with runtime dependencies (or a [build-system]) is the PROJECT profile; a pyproject carrying only [tool.*] config with no [project]/[build-system] and no uv.lock is the SCRIPTS profile. A SCRIPTS subtree must not carry a uv.lock or project/build metadata (that would misrepresent it as a shippable package); a PROJECT must.", "intentRef": "CODESTYLE.md" },

CODESTYLE.md:355

  • This paragraph says the two Python profiles differ by whether the Python has third-party runtime dependencies. A PEP 621 project can legitimately have zero runtime dependencies, so this wording can mislead readers about how python.profile.detect works. Consider describing the discriminator as presence of PEP 621 project/build metadata (and optionally uv.lock) vs tool-config-only scripts.
**Two profiles.** A repo's Python is one of two shapes, and the rest of this section (uv project, `uv.lock`, `uv run`, `src` layout, pytest coverage) describes the **project** profile. The two differ by whether the Python has **third-party runtime dependencies**, which shows up structurally in `pyproject.toml`, so the audit detects the profile there (`python.profile.detect`):

@ptr727
ptr727 merged commit 1b3b6b0 into develop Jul 17, 2026
7 checks passed
@ptr727
ptr727 deleted the support-csharp-python-shape-339 branch July 17, 2026 23:34
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