feat(owen): public facade rebrand for the CLI, Action, and SARIF identity#246
Conversation
…tity
Public product identity is "Owen" going forward - a package published
as "OwnSharp.Cli" with the permanent command "ownsharp" would have
locked the public identity to a single-language framing the project
doesn't actually have (Own.NET is language-neutral at the OwnIR/core
level and may ship a TypeScript frontend later). This is a public
facade rebrand, not an internal refactor - see
docs/notes/owen-public-facade.md for the full account of what changed
and, just as deliberately, what did not.
Public identity implemented:
- NuGet package ID: OwnSharp.Cli -> Owen.Cli (confirmed unclaimed on
nuget.org at time of writing via the v3 flat-container API)
- Tool command: ownsharp -> owen
- Action display name: "Own.NET resource-leak check" -> "Owen
lifetime/resource check"; default SARIF filename own-net.sarif ->
owen.sarif
- SARIF tool.driver.name: "Own.NET" -> "Owen" (ownlang/ownir.py +
ownlang/diag_sarif.py - the one place both the C#-facts and the
.own-diagnostics SARIF paths share)
- Cache directory: ~/.ownsharp/core/<version>/ -> ~/.owen/core/<version>/,
with a simple fallback read (not a migration subsystem) from the
previous location if a matching version was already unpacked there
- Env var: OWEN_PYTHON preferred; legacy OWN_PYTHON still works as a
temporary fallback and prints a deprecation note when it's the one
actually used
Kept unchanged (internal names, not mass-renamed): the OwnSharp.Cli
project/namespace, OwnSharp.Extractor (project + its real
ownsharp-extract.dll output filename), ownlang (package/module names,
CLI, PYTHONPATH conventions), OwnIR, every OWN0xx diagnostic code, the
Rust crates, every frontend/* directory name, historical docs/issues,
the GitHub repo name, and scripts/own-check.sh (the Action still calls
it internally). AssemblyName in the csproj stays "ownsharp" - it names
the internal dll the owen shim launches, never seen by a user, so
renaming it adds no user value.
CLI contract additions:
- `owen --help` is language-neutral at the product level while
explicitly listing the one frontend actually wired in today
("Included frontend: .NET / C# (.cs, .csproj, .sln)") - no
speculative TypeScript claim, no plugin framework added.
- Unsupported input (e.g. a .ts file, or a directory with no .cs
files) now fails explicitly with a new exit code 4 and an explicit
message, instead of silently printing "0 findings" - indistinguishable
from a genuinely clean C# scan before this change.
CheckCommand.HasSupportedInput checks this before the extractor runs.
Tests: ci.yml's ownsharp-cli-smoke job (key kept; only content changed)
now pins package ID, command name, --help framing, --version, the
unknown-command "owen:" prefix, a leak sample and a clean negative
control both run from an installed checkout-free location, the Owen
SARIF driver name, the exit-4 unsupported-input path (asserting the
literal clean-scan phrase "0 findings." does NOT appear), OWEN_PYTHON's
not-found path, and the legacy OWN_PYTHON fallback + its deprecation
note - on both ubuntu-latest and windows-latest. Every one of these
assertions was manually replicated and verified on this machine before
being written into the workflow. Two other pre-existing SARIF
driver-name assertions (ci.yml's own-check-codescan structural
validation, tests/test_diag_sarif.py, tests/test_ownir.py) were updated
to match "Owen" - caught by python tests/run_tests.py failing before
the fix, not scope creep.
PR separation: this is PR 1 of 3. Phase 3 (NuGet release pipeline, PR
#244) and Phase 4 (Marketplace preparation, PR #245) both need to be
rebuilt against this PR once merged, targeting Owen.Cli/owen and the
Owen display name instead of the pre-rebrand identity their first
drafts used. No oracle remeasurement or analyzer-semantics change is
mixed into this PR.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughThe PR renames the public CLI and SARIF identity to Owen, updates packaging and documentation, adds explicit unsupported-input exit handling, introduces content-addressed core caching with legacy fallback, changes Python environment precedence, and expands CI smoke coverage. ChangesOwen public facade
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant OwenCli
participant Extractor
participant CoreVendor
participant PythonResolver
User->>OwenCli: owen check input
OwenCli->>Extractor: expand input paths
Extractor-->>OwenCli: sources or exit code 4
OwenCli->>CoreVendor: prepare vendored core
CoreVendor-->>OwenCli: verified cache path
OwenCli->>PythonResolver: resolve Python interpreter
PythonResolver-->>OwenCli: interpreter or error
Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 377a7b1fb7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (File.Exists(legacyMarker)) | ||
| { | ||
| return legacyCacheRoot; |
There was a problem hiding this comment.
Do not reuse legacy cache without validating contents
When a machine already has ~/.ownsharp/core/0.1.0/.unpacked from the previous OwnSharp.Cli tool, this branch returns that old cache before unpacking the bundled Owen core; the package <Version> is still 0.1.0, so a same-version marker does not prove the cached Python files contain this commit's changes. In that scenario owen check --format sarif can still run the stale core that emits the old Own.NET SARIF driver (and miss any bundled core fixes), making the rebrand depend on user cache state. Please validate the legacy cache identity/content before reusing it, or force an unpack into the new .owen cache for this release.
Useful? React with 👍 / 👎.
| { | ||
| if (Directory.Exists(p)) | ||
| { | ||
| if (Directory.EnumerateFiles(p, "*.cs", SearchOption.AllDirectories).Any()) |
There was a problem hiding this comment.
Mirror the extractor's tolerant directory walk
For directory inputs this preflight uses SearchOption.AllDirectories, while the extractor's Expand walk uses EnumerationOptions { IgnoreInaccessible = true } specifically to tolerate unreadable subdirectories. If a user scans a tree with a locked/protected child and enumeration reaches it before finding a .cs file, owen now throws before the extractor can run, regressing directory scans that the underlying frontend already handles. Please use the same EnumerationOptions here.
Useful? React with 👍 / 👎.
- CoreVendor's legacy ~/.ownsharp fallback trusted a bare .unpacked
marker's existence keyed only by version. The CLI's own <Version>
doesn't change every time the vendored core's content does - this
rebrand's own SARIF-driver-name change is the concrete proof: same
0.1.0, different core content - so a machine with a pre-rebrand
OwnSharp.Cli install's ~/.ownsharp/core/0.1.0/ cache could silently
serve stale content (the old "Own.NET" driver name) to the new
Owen.Cli 0.1.0 install. Reproduced locally: seeded a legacy cache
with the pre-rebrand driver name and confirmed `owen check --format
sarif` served it unchanged before this fix.
Fixed by keying the marker on a SHA-256 fingerprint of the bundled
ownlang/*.py files' names+content instead of bare existence - same
location, both the new ~/.owen and legacy ~/.ownsharp fallback
checks now only trust a cache whose marker matches the content this
install actually bundles. Still the "simple fallback read, not a
migration subsystem" shape requested - content-aware instead of
version-only. Verified both directions locally: a stale-content
legacy cache is now correctly rejected (fresh unpack to ~/.owen),
and a legitimate matching-content legacy cache is still reused in
place without an unnecessary ~/.owen copy.
- CheckCommand.HasSupportedInput's directory walk used a plain
SearchOption.AllDirectories, which throws on a locked/permission-
denied subdirectory, while the extractor's own Expand() walk
(OwnSharp.Extractor/Program.cs) uses EnumerationOptions {
IgnoreInaccessible = true } specifically to tolerate that and keep
scanning. The new preflight check could have crashed owen check on
a directory tree the extractor itself would have handled fine.
Fixed by using the identical EnumerationOptions the extractor
already relies on.
docs/notes/owen-public-facade.md updated to record both corrections
in place, without erasing the original description of the intended
(simpler, buggier) fallback shape.
|
Both confirmed and fixed in 3585bf8:
Thanks — #1 in particular is a real correctness gap in the rebrand's own headline feature (the SARIF driver name), not a hypothetical. Generated by Claude Code |
|
@coderabbitai review |
…sensitive extensions Addresses review round 3 on PR #246 (three findings, all with committed CI regression tests, not just local verification): 1. Stale-cache pollution on a fingerprint mismatch: the round-2 fix overwrote the destination file-by-file and rewrote the marker to match the new source, but never removed a file the new source no longer had, so a removed-upstream module survived as an orphan while the marker claimed the (polluted) result was valid. CoreVendor now uses a content-addressed layout (~/.owen/core/<version>/<fingerprint>/) with no separate marker -- a fingerprint mismatch is a different path, never an in-place overwrite -- and publishes atomically (build into a temp sibling, verify the written destination's own fingerprint matches the source, then Directory.Move once). The legacy fallback now fingerprints the actual legacy destination content and only trusts it on an exact match, rejecting extra/missing/modified files instead of patching them. 2. HasSupportedInput's cheap directory check disagreed with the extractor's real expansion rules (bin/obj/generated/vendor skips), so a directory containing only skipped files passed the CLI preflight but produced zero real extractor inputs -- the exact silent-clean-scan bug exit 4 exists to prevent. Per review, the CLI no longer tries to duplicate the extractor's skip-list; the extractor itself now checks Expand(...).Distinct() and returns exit 4 with an explicit message when it's empty, and the CLI/own-check.sh's existing exit-code propagation carries that through unchanged. 3. SupportedExtensions now compares with StringComparer.OrdinalIgnoreCase so Foo.CS/App.CSPROJ are recognized like their lowercase spellings. ci.yml gains committed regression coverage (both OSes) for all of the above: matching/extra-file/modified-content legacy cache reuse and rejection, skipped-only and generated-only directories, an empty .csproj, a .sln with no projects, skipped-files-plus-real-source, an inaccessible subtree alongside a readable source, and an uppercase extension. docs/notes/owen-public-facade.md updated to describe the round-3 design. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
frontend/roslyn/OwnSharp.Cli/CoreVendor.cs (1)
157-157: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueAvoid unnecessary
ToArray()allocation in fingerprint computation.
sha.ComputeHash(buffer.ToArray())copies the entire MemoryStream contents into a new byte array. TheSHA256.ComputeHash(Stream)overload can read directly from the MemoryStream after rewinding, avoiding the allocation.♻️ Proposed refactor
writer.Flush(); - return Convert.ToHexString(sha.ComputeHash(buffer.ToArray())); + buffer.Position = 0; + return Convert.ToHexString(sha.ComputeHash(buffer));🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@frontend/roslyn/OwnSharp.Cli/CoreVendor.cs` at line 157, Update the fingerprint computation in the surrounding method to rewind the MemoryStream before hashing, then use SHA256.ComputeHash(Stream) directly instead of converting the buffer with ToArray(). Preserve the existing hexadecimal return value.docs/notes/owen-public-facade.md (1)
82-85: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueSpecify a language for the fenced code block.
The embedded CLI help excerpt uses a fenced code block without a language tag, which markdownlint flags (MD040). Add
textto the opening fence.📝 Proposed fix
Included frontend: .NET / C# (.cs, .csproj, .sln)</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@docs/notes/owen-public-facade.mdaround lines 82 - 85, Update the fenced
code block containing “Included frontend” in the Owen public facade
documentation to use the text language tag on its opening fence, leaving the
embedded CLI help content unchanged.</details> <!-- cr-comment:v1:2ce05d99f463fe7e0e058817 --> _Source: Linters/SAST tools_ </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Inline comments:
In @.github/workflows/ci.yml:
- Around line 2248-2271: Update the workflow step “Inaccessible subtree plus one
readable source -- tolerated, real source still found” to run only on Linux,
enforce that locking the directory succeeds instead of ignoring chmod failures,
and validate the command exits with status 1. Keep the output assertions
specific: require OWN001 from Real.cs and assert Secret.cs is absent, while
preserving the existing crash-check.- Around line 2079-2084: Replace python3 with python in the SARIF smoke-test
commands throughout the workflow, including the JSON validation command and the
corresponding commands near the other referenced steps. Preserve the existing
scripts and assertions while ensuring they invoke the interpreter exposed by
actions/setup-python on Windows.In
@frontend/roslyn/OwnSharp.Cli/CoreVendor.cs:
- Around line 112-120: Update the publication flow around CoreVendor’s
Directory.Move so an IOException caused by another process creating finalOwnlang
after the Directory.Exists check is treated as a lost race: return finalRoot
after confirming the destination now exists, while preserving propagation of
unrelated move failures and existing cleanup behavior.
Nitpick comments:
In@docs/notes/owen-public-facade.md:
- Around line 82-85: Update the fenced code block containing “Included frontend”
in the Owen public facade documentation to use the text language tag on its
opening fence, leaving the embedded CLI help content unchanged.In
@frontend/roslyn/OwnSharp.Cli/CoreVendor.cs:
- Line 157: Update the fingerprint computation in the surrounding method to
rewind the MemoryStream before hashing, then use SHA256.ComputeHash(Stream)
directly instead of converting the buffer with ToArray(). Preserve the existing
hexadecimal return value.</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: Path: .coderabbit.yaml **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `6936e18b-8255-41fa-8d55-0621e6b9862a` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 4c5a86b176b04c42f7c1cc9e51aef545a3586cc9 and 9e2a758bac0a584dd91cabf2d45ae9e988855e8a. </details> <details> <summary>📒 Files selected for processing (18)</summary> * `.github/workflows/ci.yml` * `README.md` * `README.ru.md` * `action.yml` * `docs/notes/alpha-readiness.md` * `docs/notes/owen-public-facade.md` * `frontend/roslyn/OwnSharp.Cli/CheckCommand.cs` * `frontend/roslyn/OwnSharp.Cli/CoreVendor.cs` * `frontend/roslyn/OwnSharp.Cli/OwnSharp.Cli.csproj` * `frontend/roslyn/OwnSharp.Cli/Program.cs` * `frontend/roslyn/OwnSharp.Cli/PythonResolver.cs` * `frontend/roslyn/OwnSharp.Cli/README.md` * `frontend/roslyn/OwnSharp.Cli/ToolVersion.cs` * `frontend/roslyn/OwnSharp.Extractor/Program.cs` * `ownlang/diag_sarif.py` * `ownlang/ownir.py` * `tests/test_diag_sarif.py` * `tests/test_ownir.py` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
- ci.yml: use `python` instead of `python3` in the CLI smoke job's SARIF driver-name assertions -- actions/setup-python does not expose a python3 alias on windows-latest, so these would have broken the Windows leg. - ci.yml: the inaccessible-subtree test is now Linux-only (chmod 000 does not reliably lock out the job's own account on Windows) and actually proves the lockout worked -- asserts exit 1 and that the output names Real.cs but never Secret.cs, instead of a bare "OWN001 somewhere" check that would pass just as well if the locked file got analyzed too. - CoreVendor.cs: close the narrow TOCTOU window between the Directory.Exists(finalOwnlang) race check and Directory.Move -- a concurrent `owen` process publishing the same fingerprint in between now resolves the same way the earlier check already did (their content is provably identical), instead of surfacing Move's IOException. - CoreVendor.cs: Fingerprint hashes the MemoryStream directly (rewound) instead of copying it via ToArray() first. - owen-public-facade.md: language tag on the --help excerpt's code fence. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw
|
All three findings fixed, with the two required reproductions now committed as Also fixed in
Generated by Claude Code |
…existence Round-4 review finding: a hit at the content-addressed ~/.owen/core/<version>/<fingerprint>/ownlang path was trusted on Directory.Exists alone, and the two concurrent-publisher race checks around the atomic move made the same assumption. A path name is only a claim, not proof -- a destination already sitting at the "right" fingerprint could be modified, corrupted, or hand-assembled after publication and would then be served as valid. Every current-path hit now recomputes the fingerprint over what is actually on disk and only trusts an exact match, the same standard the legacy-cache fallback already held itself to. A mismatch quarantines the invalid destination (atomic rename to a .invalid-<guid> sibling, then best-effort recursive delete -- no in-place delete a concurrent reader could observe mid-way) and falls through to the same temp-directory + atomic-move rebuild a fresh unpack uses. Added the round-4 regression to ci.yml: create the current cache, tamper ownir.py and add a stale_module.py directly under the fingerprint-named path, and assert the second run rejects it, rebuilds clean, and the stale file is gone from whatever cache directory actually got used. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw
…facade (P-013) * feat(owen-cli): release-readiness pipeline, rebuilt against the Owen facade (P-013) Rebuild of PR #244's release-prep work directly against post-#246 main, using the Owen public identity throughout instead of the pre-rebrand ownsharp/OwnSharp.Cli names PR #244 used (per review: do not merge the old-brand version, rebuild it against the merged facade). Package metadata (OwnSharp.Cli.csproj) — added Authors, PackageProjectUrl, RepositoryUrl, RepositoryType, PackageTags, PackageReadmeFile, and deterministic-pack properties (Deterministic, ContinuousIntegrationBuild) on top of #246's already-Owen-branded PackageId/ToolCommandName/Description -- these are additive metadata, not a rebrand of what #246 already set. PackageLicenseExpression is deliberately left unset: the repository has no LICENSE file, and choosing one is the repository owner's call, not this session's -- flagged as the first blocker in the release checklist, not resolved unilaterally. New release workflow (.github/workflows/owen-cli-release.yml, replacing PR #244's ownsharp-cli-release.yml under the Owen tag namespace owen-cli-v*): build-test-pack -> smoke-test (ubuntu + windows) -> publish. The smoke-test job installs and exercises the already-packed Owen.Cli artifact from build-test-pack's upload -- no checkout, no rebuild, no invocation of the pre-rebrand `ownsharp` command -- verifying `owen --version`, a leak sample (exit 1, OWN001), a clean sample (exit 0), the OWEN_PYTHON-not-found actionable-failure path (exit 3), and a full uninstall/reinstall cycle. Publish still requires both a pushed owen-cli-v* tag (workflow_dispatch can never reach it) and a `nuget-release` GitHub Environment a repo admin has to configure with required reviewers -- it doesn't exist yet. Internal filenames (ownsharp.dll, ownsharp-extract.dll -- the real, unmodified AssemblyName-derived output, per #246's established internal/ public split) are intentionally left as-is in the package-content inspection step; only the public package ID, command name, tag namespace, and env var are Owen-branded. docs/notes/owen-cli-release.md (replacing PR #244's ownsharp-cli-release.md) documents the versioning policy, the verified determinism findings (re-verified against this exact source: two packs, byte-for-byte identical payload, only NuGet's own per-pack OPC wrapper GUID differs), the metadata audit, and the release checklist -- including the license blocker addressed explicitly to the repository owner. Every step in the new workflow was manually replicated and verified locally before being encoded: dotnet pack (twice, for determinism) -> diff unzipped payload -> package-content inspection -> isolated-feed install -> owen --version / leak / clean / OWEN_PYTHON-not-found / uninstall-reinstall, all matching what the workflow asserts. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw * owen-cli-release: fail loudly if nuget-release lacks protection rules Codex review (P1): GitHub auto-creates a referenced-but-never-configured environment on first use, with zero protection rules. `environment: nuget-release` alone is therefore not proof a human ever approves this job -- if the environment is never actually set up under Settings -> Environments and NUGET_API_KEY already exists as a repository secret, a tag push could reach `dotnet nuget push` with no approval at all, silently defeating the safety story the workflow documents. The publish job's first step now queries the GitHub API for the environment's protection_rules and refuses to publish -- fails loudly, before the artifact is even downloaded -- when that array is empty, converting "never configured" from a silent bypass into a loud failure. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw * owen-cli-release: exercise the workflow on PRs, require actual reviewers Two independent review findings, both closed: 1. owen-cli-release.yml only triggered on tag push / workflow_dispatch, so a green PR check never actually ran build-test-pack -> smoke-test on either OS -- only a real tag push did, and PRs never push tags. Added a pull_request trigger scoped to the paths that matter (the CLI/extractor projects, ownlang, the workflow file itself, the shared protection script). The publish job's existing tag-push condition is unchanged, so it stays skipped on pull_request exactly as it already was on workflow_dispatch. 2. The environment-protection check (`.protection_rules | length`) accepted ANY protection rule -- a wait_timer-only or branch_policy-only environment, or a required_reviewers rule saved with zero reviewers, none of which actually gate on a human. Extracted the real predicate into scripts/check_environment_protection.sh: accepts only a required_reviewers rule with >=1 reviewer. The publish job now checks out just scripts/ (sparse), fetches the environment via `gh api` into a file, and calls the script. Its permissions gained `actions: read`, which the environment-read endpoint requires alongside `contents: read`. Fixture-driven, offline test in ci.yml's new environment-protection-selftest job (runs on every ordinary push/PR, no GitHub API or real Environment needed): zero rules, wait_timer-only, branch_policy-only, and required_reviewers-with-zero-reviewers all reject; required_reviewers with one reviewer accepts. The same script and fixtures will also back action-marketplace-readiness.yml's analogous move-major-tag check (PR #248, stacked on this branch for now -- duplication is temporary until #247 merges and #248 rebases cleanly onto main). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw * owen-cli-release: fix doc drift, close two script-injection nitpicks CodeRabbit review: - docs/notes/owen-cli-release.md quoted the publish gate as just `startsWith(github.ref, 'refs/tags/owen-cli-v')`, dropping the `github.event_name == 'push'` half the workflow's own comment explains is required to block a `workflow_dispatch --ref owen-cli-vX` bypass -- the exact scenario the doc's next sentence claimed was already impossible. Quoted the real condition in full. - `${{ steps.version.outputs.version }}` (grep'd from the csproj, which this workflow now also builds on pull_request) and `${{ needs.build-test-pack.outputs.version }}` were both inlined directly into run: scripts at five sites -- the same expression-into-shell-text pattern zizmor flags elsewhere in this repo. Both now flow through env: (a job-level OWEN_CLI_VERSION for smoke-test's four sites, a step-level CSPROJ_VERSION for the tag/version-match assertion) instead of raw interpolation. Not implemented: CodeRabbit's NuGet Trusted Publishing (OIDC) suggestion for the publish step. Real publication is already blocked on the license and Environment decisions the docs already flag as the repository owner's call, not this session's; swapping the auth mechanism before either of those is resolved is the same category of decision, not a code fix. Re-verified locally end-to-end after the env: refactor: pack, isolated-feed install, `owen --version`, and the full uninstall/reinstall cycle all still pass with the version flowing through the environment instead of inline interpolation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSXTDuh1ZHdQc4QqmYwshw --------- Co-authored-by: Claude <noreply@anthropic.com>
Что и зачем
Public-facade rebrand — not an internal refactor. Per direction: pause the NuGet publication work (PR #244) and introduce this as a separate PR, to land before Phase 3/Phase 4 so neither publishes the first real package under a C#-locked identity (
OwnSharp.Cli/ownsharp) that doesn't match how the project actually wants to present itself (language-neutral product "Owen", currently shipping a .NET/C# frontend, with a TypeScript frontend possible later).Public identity implemented:
OwnSharp.Cli→Owen.Cli(confirmed unclaimed on nuget.org via the v3 flat-container API at time of writing — worth a final re-check immediately before an actual publish)ownsharp→owenOwen lifetime/resource check; default SARIF filename →owen.sariftool.driver.name→Owen(the one shared point inownlang/ownir.py+ownlang/diag_sarif.py)~/.owen/core/<version>/, with a simple fallback read (not a migration subsystem) from~/.ownsharp/core/<version>/if that exact version is already unpacked thereOWEN_PYTHONpreferred; legacyOWN_PYTHONstill works as a temporary fallback and prints a deprecation note when it's the one actually usedKept unchanged (internal names — not mass-renamed): the
OwnSharp.Cliproject/namespace,OwnSharp.Extractor(project + its realownsharp-extract.dlloutput filename),ownlang(package/module/CLI),OwnIR, everyOWN0xxcode, the Rust crates, everyfrontend/*directory name, historical docs/issues, the GitHub repo name, andscripts/own-check.sh(the Action still calls it internally).AssemblyNamein the csproj staysownsharp— it names the internal dll theowenshim launches, never seen by a user.CLI contract additions:
owen --helpis language-neutral at the product level, while explicitly listingIncluded frontend: .NET / C# (.cs, .csproj, .sln)— no speculative TypeScript claim, no plugin framework.4, explicit message) instead of silently printing "0 findings" — previously indistinguishable from a genuinely clean scan.CheckCommand.HasSupportedInputchecks this before the extractor runs.Full account (including the deliberate non-changes and the reasoning) is in
docs/notes/owen-public-facade.md.Тип изменения
Как проверено
python tests/run_tests.py— 276/276 (two pre-existing SARIF-driver-name pins intests/test_diag_sarif.py/tests/test_ownir.pyupdated from"Own.NET"to"Owen"— caught by the suite failing before the fix, not scope creep)ruff check ./mypy— cleanpython3 -c "import yaml; yaml.safe_load(...)"ci.yml: build → packOwen.Cli→ install via an isolatednuget.config→owen --help/--version/unknown-command → leak sample (exit 1,OWN001) → clean sample (exit 0) → SARIF driver name isOwen→ unsupported input (exit 4, explicit message, confirmed the literal clean-scan phrase0 findings.does not appear) →OWEN_PYTHONnot-found path (exit 3) → legacyOWN_PYTHONfallback (resolves + prints deprecation note) → fresh-install cache goes to~/.owen/, pre-existing~/.ownsharp/cache is reused in placeСвязанные issue
Refs #202, P-013. Supersedes the branding assumptions in PR #244 and PR #245's first drafts — both will be rebuilt against this PR once merged.
Чеклист
ownsharp-cli-smoke(job key kept, content rewritten) pins every piece of the new contract on both OSes; every assertion was hand-verified locally firstREADME.md/README.ru.md,frontend/roslyn/OwnSharp.Cli/README.md,docs/notes/alpha-readiness.md(active install/usage instructions only — no historical note rewritten), newdocs/notes/owen-public-facade.mdfeat:)PR separation
Owen.Cli/owen.Owen lifetime/resource checkdisplay name.No oracle remeasurement or analyzer-semantics change is mixed into this PR — the extractor and every diagnostic verdict are byte-for-byte unchanged.
Generated by Claude Code
Summary by CodeRabbit
New Features
owen checkvia theOwen.Clipackage.OWEN_PYTHON, with deprecatedOWN_PYTHONfallback.owen.sarif.Documentation
Tests / CI