com.romanilyin.canonicalpath
v2026.6.14-1
Published
CanonicalPath lexical identity, scoped PathGuard validation, and daemon transport for Unity editor/tooling integrations.
Maintainers
Readme
Unity CanonicalPath Package
Status: early managed CanonicalPath runtime plus bridge facade scaffold. CanonicalPath, CanonicalPathBurst, CanonicalFSDaemonHttpClient, ICanonicalPathService, CanonicalPathValue, PathGuard, and ScopedPathGuard are present for lexical identity, Burst-compatible unsafe buffer helper shape, daemon transport, bridge payload validation, and Unity MCP scope validation; the Unity 2022.3 / 6000.1 / 6000.2 / 6000.3 / 6000.4 EditMode and Burst allocation matrix is active locally. Full Unity package hardening remains planned. The TypeScript gateway skeleton lives in @romanilyin/canonicalpath/unity-gateway.
CanonicalPath for Unity is a client/bridge surface: managed lexical identity, scoped PathGuard validation, daemon transport, and Burst-oriented helper shape for editor/tooling integrations.
Unity code is not an independent filesystem security boundary. Security-sensitive filesystem I/O should delegate to the Go CanonicalFS daemon unless a native root-bound implementation is separately reviewed and documented.
CanonicalPath behavior is tracked in shared vectors at spec/testdata/*.json and consumed by the local C# smoke gate via pnpm unity:canonicalpath:vectors. Bridge payload behavior is tracked in shared vectors at spec/testdata/unity_bridge_vectors.json; the TypeScript gateway and local C# smoke gate consume these vectors today. Unity MCP scope behavior is tracked in spec/testdata/unity_mcp_path_scope_vectors.json and consumed by TypeScript, Go, and local C# smoke gates through pnpm unity:mcp:path-scopes:vectors. pnpm unity:burst:surface checks the no-string unsafe buffer helper shape under dotnet. pnpm unity:burst:probe is a default-skipped optional compiler probe; set UNITY_BURST_PROBE=1 to run it against an installed Unity Editor and com.unity.burst. pnpm unity:burst:alloc is a default-skipped optional allocation probe; set UNITY_BURST_ALLOC_PROBE=1 to compile a Burst function pointer, warm it up, and assert zero managed allocations around the Burst workload. pnpm unity:editmode:matrix runs the active local versioned EditMode lanes, and pnpm unity:burst:alloc:matrix runs the active local versioned Burst allocation lanes.
Unity local matrix coverage is active for these editor/runtime lanes:
- Unity
2022.3managed C# local EditMode coverage. - Unity
2022.3Burst-compatible C# local allocation coverage. - Unity
6000.1managed C# local EditMode coverage. - Unity
6000.1Burst-compatible C# local allocation coverage. - Unity
6000.2managed C# local EditMode coverage. - Unity
6000.2Burst-compatible C# local allocation coverage. - Unity
6000.3managed C# local EditMode coverage. - Unity
6000.3Burst-compatible C# local allocation coverage. - Unity
6000.4managed C# local EditMode coverage. - Unity
6000.4Burst-compatible C# local allocation coverage.
Local package use:
- Add
packages/unity/package.jsonthrough Unity Package Manager's local package flow, or use a manifestfile:dependency pointing atpackages/unity. - The package does not declare
com.unity.burstas a default dependency; Burst probes create temporary projects that includecom.unity.burstexplicitly. - Treat this package as an early bridge/runtime package, not as the final full Unity package target.
Scoped registry use through npmjs:
{
"scopedRegistries": [
{
"name": "npmjs",
"url": "https://registry.npmjs.org",
"scopes": ["com.romanilyin"]
}
],
"dependencies": {
"com.romanilyin.canonicalpath": "2026.6.14-1"
}
}Release packaging:
- Package version for the current Unity registry release candidate is
2026.6.14-1. - npmjs package coordinate:
[email protected]. - Git UPM by repository tag remains available for the earlier source release:
https://github.com/romanilyin/canonicalpath.git?path=/packages/unity#2026.5.18-2. - npm prepack sync copies root
LICENSE.md,LICENSE.ru.md,NOTICE.md, and their Unity.metafiles into the package tarball before publication, then removes unchanged copies after packing. - Default npm publication is currently unsigned:
pnpm unity:npm:publish. Unity 6.3+ will showSignature: Missingfor that artifact. - Optional Unity-signed publication uses
pnpm unity:pack:signedandpnpm unity:npm:publish:signed, which run UPM CLIupm pack, verify.attestation.p7m, and publish the signed tarball fromtmp/unity-signed. - Token-based npm publication uses a local ignored root
.envfile withNPM_TOKEN; optional signed publication also needsUPM_ORGANIZATION_ID,UPM_SERVICE_ACCOUNT_KEY_ID, andUPM_SERVICE_ACCOUNT_KEY_SECRET. Do not commit real tokens, service account credentials, or local.npmrcfiles.
Implemented early bridge scope:
- Minimal
ICanonicalPathServicefacade inside the Unity bridge, not a standalone large library project. CanonicalPathValuevalue wrapper for normalized bridge paths.- Managed lexical
CanonicalPathAPI covered by shared canonicalpath vectors. PathGuardfor agent payload validation before any Unity write command.ScopedPathGuardfor lexical Unity MCP scopes; this is not a filesystem security boundary.- Unity asset path conversion for
Assets/...andPackages/...only. - Generated filename sanitization for bridge-created assets and modules.
UnityBridgeBuiltinsfor status, project info, recent logs, validated text reads, and path validation.- Guarded write dispatch for
assets.refresh,scene.save,asset.import, and prefab/module command contracts. - Shared Unity bridge vectors for payload paths and generated filenames.
- Shared Unity MCP scoped path vectors for TypeScript, Go, and local C# smoke gates.
- Local managed C# vector smoke via
pnpm unity:canonicalpath:vectorswhendotnetis available. - Local C# vector smoke via
pnpm unity:bridge:vectorswhendotnetis available. - Local managed C# allocation smoke via
pnpm unity:canonicalpath:allocwhendotnetis available. - Local managed daemon transport smoke via
pnpm unity:canonicalfs:transport:smokewhendotnetand Go are available; daemon client calls exposeCancellationTokenoverloads so Unity tools can bound editor-side waits. - Local Burst-compatible unsafe buffer surface smoke via
pnpm unity:burst:surfacewhendotnetis available. - Optional Unity Burst compiler probe via
UNITY_BURST_PROBE=1 pnpm unity:burst:probewhen Unity Editor andcom.unity.burstare available. - Optional Unity Burst allocation probe via
UNITY_BURST_ALLOC_PROBE=1 pnpm unity:burst:allocwhen Unity Editor andcom.unity.burstare available. - Active Unity Burst allocation matrix via
pnpm unity:burst:alloc:matrixfor local2022.3,6000.1,6000.2,6000.3, and6000.4editors. - Unity EditMode matrix via
pnpm unity:editmode:matrixwhen Unity Editor is available throughUNITY_EDITOR,UNITY_EXE, or the Unity Hub install path.
Facade:
public interface ICanonicalPathService
{
CanonicalPathValue Normalize(string input);
CanonicalPathValue NormalizeProjectRoot(string input);
CanonicalPathValue FromUnityAssetPath(CanonicalPathValue projectRoot, string unityPath);
string ToUnityAssetPath(CanonicalPathValue projectRoot, CanonicalPathValue fullPath);
void AssertInsideProject(CanonicalPathValue projectRoot, CanonicalPathValue candidate);
string MakeSafeFileName(string input, int maxLength);
}PathGuard must:
- Reject null / empty where invalid.
- Reject NUL.
- Normalize separators.
- Reject absolute paths from agent payloads.
- Allow only
Assets/...andPackages/...Unity paths. - Reject
../traversal. - Assert candidate paths stay inside the Unity project root.
- Sanitize generated filenames.
UnityBridgeBuiltins validates every write command with PathGuard. Inside the Unity Editor it can execute assets.refresh, asset.import, and scene.save; prefab/module creation remains a validated command contract until a bridge-specific implementation is added.
Full package scope:
- Broader Unity Editor UX wiring for managed
canonicalpathand daemon transport. - Broader Burst-compatible lexical helpers and real Burst compiler tests.
- Unity Editor UX wiring for managed daemon transport.
Security boundary:
- Unity code is client-side identity/transport code only.
- Early
PathGuardis bridge payload validation, not a TOCTOU-proof filesystem security boundary. ScopedPathGuardis lexical scope validation only; it does not inspect symlinks, reparse points, races, or host filesystem behavior.- Security-sensitive filesystem access must delegate to the Go daemon or a separately reviewed native root-bound implementation.
- Cancellation tokens only bound client waits; they do not change daemon-side root-bound authorization or filesystem semantics.
Allocation gate plan:
- Managed lanes use Unity EditMode tests to assert behavior and bounded GC allocations for hot lexical loops.
- Before Unity Editor lanes are available,
pnpm unity:canonicalpath:allocprovides a local dotnet managed allocation smoke for the lexical API. pnpm unity:burst:surfaceverifies the current no-string unsafe buffer helper shape with zero managed allocations under dotnet.UNITY_BURST_PROBE=1 pnpm unity:burst:probecompiles and invokes a small Burst function pointer over that helper shape when Unity Editor andcom.unity.burstare available.UNITY_BURST_ALLOC_PROBE=1 pnpm unity:burst:alloccompiles and invokes a Burst function pointer after warmup, then asserts zero managed allocations around the Burst workload.pnpm unity:burst:alloc:matrixruns active local Unity2022.3,6000.1,6000.2,6000.3, and6000.4Burst allocation lanes and skips missing editors.- Individual versioned lanes are available as
pnpm unity:burst:alloc:2022.3,pnpm unity:burst:alloc:6000.1,pnpm unity:burst:alloc:6000.2,pnpm unity:burst:alloc:6000.3, andpnpm unity:burst:alloc:6000.4. - Keep every Unity lane tracked in
spec/language-targets.json.
