feat(workspace): allow creation without an initial repository

Keep bootstrap, signing identity, config and resource-key allocation atomic with optional Repository intent. Preserve repository-present fingerprints for saved receipts; replay reads current authority at the initial key and never recreates missing assets.

Provide explicit repository-free CLI creation, optional TUI/Web creation inputs, nullable generated contracts, and valid empty catalog/Worker paths. Retain existing authenticated non-owner viewing policy pending the T-717 authorization decision.

Validation: root cargo check; server tests 639 lib + 11 bin; server-api 70 default / 77 typescript; client 52 lib + 2 integration; tui 337; yoi 11 lib + 120 bin. OpenAPI/TS freshness, cargo fmt and diff checks pass. Web check/build, 18 model tests, 268 component tests and Chromium 8 width/theme combinations pass; before/after visual evidence is documented in web/workspace/test/visual-review. Full Web suite has one independently reproduced baseline Ticket source-policy failure.
This commit is contained in:
2026-10-08 18:34:44 +09:00
parent e939cd4e4b
commit 7919616db5
37 changed files with 2335 additions and 354 deletions
@@ -0,0 +1,135 @@
{
"schemaVersion": 1,
"id": "optional-initial-repository",
"title": "Optional initial repository and empty Workspace",
"baseUrl": "http://127.0.0.1:15281",
"colorScheme": "light",
"reducedMotion": "reduce",
"personas": [
{
"id": "fixture",
"label": "Synthetic account; permissions vary by Workspace",
"auth": {
"kind": "anonymous"
}
}
],
"viewports": [
{
"label": "desktop",
"width": 1440,
"height": 900
},
{
"label": "narrow",
"width": 768,
"height": 900
},
{
"label": "mobile",
"width": 390,
"height": 844
}
],
"routes": [
{
"id": "catalog",
"label": "Create Workspace without a repository",
"path": "/",
"goal": "Reopen a zero-repository Workspace or create a new Workspace without configuring Git.",
"dataState": "Accessible Workspaces with no repositories and blank creation form.",
"ready": {
"kind": "selector",
"selector": ".workspace-create-panel input"
},
"capturePoints": [
{
"id": "initial",
"label": "Blank creation form",
"fullPage": true
}
]
},
{
"id": "empty-owner",
"label": "Empty Workspace owner",
"path": "/w/home-empty",
"goal": "Use Home and Sidebar without any repositories or work records.",
"dataState": "Owner permissions; zero repositories, Workers, tickets, Objectives, and Merge Requests.",
"ready": {
"kind": "selector",
"selector": ".workspace-home:has([data-feed-ready='home-attention']):has([data-feed-ready='home-active']):has([data-feed-ready='home-recent'])"
},
"capturePoints": [
{
"id": "initial",
"label": "Empty Home and Sidebar"
}
]
},
{
"id": "member",
"label": "Zero-repository member",
"path": "/w/home-member",
"goal": "Navigate authorized work without owner-only repository management actions.",
"dataState": "Non-owner permissions; zero repositories, representative work records.",
"ready": {
"kind": "selector",
"selector": ".workspace-home:has([data-feed-ready='home-attention']):has([data-feed-ready='home-active']):has([data-feed-ready='home-recent'])"
},
"capturePoints": [
{
"id": "initial",
"label": "Member Home and Sidebar"
}
]
},
{
"id": "worker",
"label": "New Worker without repositories",
"path": "/w/home-empty/workers/new",
"goal": "Start a normal conversation Worker without a Workdir on embedded Runtime.",
"dataState": "No repositories or Workdirs, embedded and remote Runtime candidates.",
"ready": {
"kind": "selector",
"selector": ".worker-launch-form"
},
"capturePoints": [
{
"id": "initial",
"label": "Embedded Worker launch",
"fullPage": true
}
]
}
],
"processes": [
{
"id": "workspace-fixture",
"command": "deno",
"cwd": "../../../../tools/web-ux",
"args": [
"run",
"--allow-net",
"--allow-read",
"browser-tests/workspace_home_fixture_server.ts",
"15282",
"../../web/workspace/build"
],
"readyUrl": "http://127.0.0.1:15282/health"
},
{
"id": "empty-workspace-api",
"command": "deno",
"cwd": "../..",
"args": [
"run",
"--allow-net",
"test/visual-review/empty-workspace-fixture-server.ts",
"15281",
"http://127.0.0.1:15282"
],
"readyUrl": "http://127.0.0.1:15281/health"
}
]
}