Project Settings
Project settings let you configure how Trinity manages your project's git workflow, automation, AI models, secrets, and more.
Accessing Settings
Click Settings inside the Project section of the sidebar (the one directly below the project's own nav items), or navigate to /projects/{id}/settings.
The page holds two tiers of the same field set, and a Mine | Project toggle at the top picks which one you are writing:
- Project — what everyone working on the project gets, across the full tab set: General, Business, Git, AI Models, Secrets, Stack, Worktrees, and Danger.
- Mine — your own defaults for your runs on this project, like a personal
.env.localfor it. Three tabs, one panel each: General → Automation, Git → Identity, and AI Models → Models. Anything you leave unset follows Project, then the workspace, and nothing you set here is visible to, or affects, anyone else.
Most of what a project holds is one answer for everyone on it — its repos, its collaborators, its secrets, its stack, where its assets live — so those tabs sit under Project alone. The two tiers are one page rather than two because they are adjacent rungs of one cascade: the value you override under Mine is the one Project is answering, and it is a click away instead of a page away. Flipping the toggle keeps you on the tab you were reading wherever both tiers have it, and falls back to the first tab the new tier does have when they don't.
Linking into it
The page's address carries where you are in it, so a link can name a tab, a panel, and which tier to open on:
/projects/{id}/settings?scope=<member|project>&tab=<tab>&sub=<panel>
scope is the tier — member for Mine, project for Project — and an address that names none opens on Project. tab and sub name the section and the panel inside it. Anything the active tier can't show falls back to the first thing it can, rather than to an empty panel, and the address keeps what you asked for — so flipping the toggle to the tier that does have it takes you straight there.
General
Details
- Project name — display name used throughout the UI (also seeds the GitHub repo name for new projects)
- Description — short summary shown in project lists
Accessibility
Visible only when at least one of your packages ships a UI-bearing target. A WCAG 2.1 picker per package (A, AA, AAA, or off), each row labelled by the artifacts that package ships — a polyrepo can hold a marketing site at AA next to an internal admin tool with no a11y requirement. The level sits on the package because accessibility is written: semantic markup, focus order, contrast, ARIA. It constrains the code at one manifest root, and a component two artifacts share cannot be written two ways — so a React Native codebase shipping both a Mobile and a Web App target gets one answer, not two. Each level propagates into the design guide and the per-story prompts for work landing in that package. Releases use the strictest level across the whole project.
Design Systems
Your project's design systems live on their own tab — each one's themes, showing that theme's palette and typography as swatches and type samples plus its motion scale, and, on the system itself, any design notes it carries (the intent you agreed on that isn't a token, like "dense, information-first layouts" or "never gradients"). Themes are grouped under the design identity they belong to — a name covering a set of looks, nothing to do with the git Identity further down this page. A system that names them — "Vintage" and "Modern", say — shows each as its own labelled cluster, while every theme you never named one for sits together in a single unlabelled group, so a system that names none at all reads as the plain list of themes it always was. Design systems are created during Architect planning or pulled from your code on import; once the project has one, you review it here. Agents write generated UI against these tokens and read the notes alongside them, so what you see on this tab is what your build renders.
Automation Toggles
Cascade defaults from Trinity's own defaults → workspace → my workspace → project → my project → entity → job. Under Project, a toggle overrides the workspace default for everyone on the project; flip the page to Mine and the same toggle overrides it for your own runs alone.
| Toggle | Effect |
|---|---|
| Reviewers per Story | How many reviewers audit each story, 1 to 10 (a checkpoint reads it as audit → fix iterations); a story can set its own on its page |
| Auto-merge | Merge PRs automatically when checks pass |
| Squash merge | Use squash merges instead of merge commits |
| Delete story branch after merge | Delete a story's own branch once its PR merges |
| Delete release branch after merge | Delete the release branch once the release has shipped |
| Skip asset check | Bypass the missing_assets execution gate (analyst stops declaring) |
| Skip business details check | Bypass the missing_business_details execution gate |
| Skip checkpoint asset audit | Skip the full-worktree image-placeholder scan at quality checkpoints |
| Skip checkpoint business audit | Skip the contact-placeholder scan at quality checkpoints |
| Skip release asset audit | Skip the image scan at release approval |
| Skip release business audit | Skip the contact scan at release approval |
| Auto-approve quality checkpoints | Run full QA but skip the human gate (release gates are always manual) |
| Auto-approve technology deviations | Skip the approval gate when the analyst proposes a technology deviation (it still surfaces in the PR) |
Pull requests without verified checks sits below the toggles and is a choice rather than a switch. It decides what happens when a pull request has no checks at all, or checks that finished without passing — skipped, cancelled, or neutral, which is what a CI workflow limited to certain paths reports for a change outside them. Ask me (the default) pauses the merge at the Checks Unverified gate; Merge without them goes ahead without asking. Answering that gate with Always go ahead in this project sets it for you. A failing check stops the merge whatever this says, and so do checks still running. It follows the same cascade as the toggles, and the workspace and Mine automation cards carry it too.
Audit Codebase
Runs the same placeholder scan that checkpoint + release gates run, on demand. Scans the whole worktree for image placeholders (placeholder.svg, picsum.photos, Lorem ipsum) and contact placeholders (example.com, 555-*, John Doe, stale copyright years), groups findings per file with line refs, and shows AI-suggested replacements (AI triage classifies the findings automatically). Informational only; nothing blocks and no gate fires.
Placeholder Audit Excludes
Add glob patterns to exclude from placeholder scans on top of the built-in excludes (node_modules/, **/__tests__/**, etc.). A .trinityignore file at the worktree root is also respected (gitignore syntax).
Permission Overrides
Override the workspace's permissions for this specific project. Each permission resolves as project → workspace → default (owner).
| Permission | What it gates |
|---|---|
| Manage secrets | Editing project / workspace secrets |
| Delete project | Archiving / hard-deleting the project |
Values: owner (workspace owners and managers only) or all (any member).
Project Assets
Manage uploaded reference files (wireframes, brand assets, specs, screenshots). See Project Assets.
Storage
Configure where project assets are stored:
| Option | Description |
|---|---|
| Local Only | Files stay on your machine. Not available in a shared workspace (assets must be reachable from every member's machine). |
| Trinity Cloud | Managed Cloudflare R2 storage. No setup needed. Default in a shared workspace. |
| BYO S3-Compatible | Bring your own bucket — AWS S3, Cloudflare R2, Backblaze B2, DigitalOcean Spaces, MinIO, etc. Configure endpoint, region, bucket, access key, and secret key. |
Trinity Cloud limits: each person gets a single 10 GB managed pool, shared across every workspace they own. A workspace doesn't get a bucket of its own — its bytes come out of its owner's pool. Adding members never grows the pool.
- A workspace you own: you charge your own 10 GB pool. While the closed beta runs that pool is the whole of it — add-on packs aren't on sale, so BYO S3 is what takes a project past 10 GB. Once the beta opens, 10 GB add-on packs ($5/mo each, no cap on how many you can stack) attach on top of it.
- A workspace you don't own: uploads charge the workspace owner's pool. If the owner's pool is full, your upload is blocked — the error names the owner so you know whose pool needs more space.
- BYO S3 / Local Only: no Trinity-imposed limits. Switch to BYO S3 when you need real volume without growing the owner's managed pool.
When you hit the cap, the upload that would push you over blocks immediately, and the pool owner has a 7-day grace period to fix it. Once that grace period fully elapses, every new upload blocks — even one that would otherwise fit — until the pool owner frees space or moves projects onto BYO S3. Once the beta opens, buying an add-on pack clears the block too. Reading or downloading files you've already stored is never blocked, at any point.
The quota bar warns before it blocks. With Trinity Cloud selected, the card shows a usage bar for the pool the project draws on, and the line under it changes as that pool fills:
| Pool used | Bar | What the line says |
|---|---|---|
| Up to 80% | Neutral | What the pool gets you and how to get more. In a workspace you don't own, it names the owner and points at BYO S3 for real volume |
| Over 80% | Amber | "Your pool is nearly full", then what to do about it |
| Over 95% | Red | "Your pool is almost full — uploads may fail", then the same |
A warning names the pool for whoever owns it — Your pool in a workspace you own, Sofia's pool in one you don't — so it always says whose space is running out. What it tells you to do follows the same rule as the bullets above: while the closed beta runs it points at BYO S3, and once the beta opens it offers an add-on pack as well — yours to buy in a workspace you own, the owner's to buy in one you don't.
The attachment picker uses the same wording. An upload that would overrun the pool is refused before it starts, with an error naming the pool, what it's using of what it has, and the same remedy.
Business
Company / product information used by execution gates and agent-generated content:
- Company / product name
- Tagline
- Contact email and phone
- Address
- Legal name and copyright
- Social media links
These are initially extracted from onboarding and can be edited at any time. Stories that need branding or contact info check these fields — missing values pause with a missing_business_details gate (unless you've turned on Skip business details check).
Git
Destination, Branching Strategy, Release Defaults, Promotion, Repositories and Collaborators are the project's own — one answer for everyone working on it. Identity is yours: it sits under Mine, and every other member of the project holds their own.
Destination
Where this project creates repositories — the git host and workspace (owner/organization) — plus the account Trinity acts as when it creates and pushes them. The project inherits the scope default until you override it here.
- Host + workspace — the resolved destination, with an inherit/override badge and a Change button that opens the picker. Reset to global drops a project override back to the scope default.
- Acting as — the connected account Trinity authenticates as for this project's git operations, with an expiry hint and a re-authenticate prompt if the credential has lapsed.
- Advanced: per-repo destinations — send individual repos to a host or workspace different from the project's destination.
Once any repo has been created, its location locks. A created repo lives at its remote URL, and changing the destination can't move it — so the host and workspace become read-only with a note like "Repos already live in {owner} · {host} — relocating repos isn't supported yet.", and the reset link hides. You can still change the connection method (HTTPS/SSH) and the acting-as account, since neither moves a repo. Per-repo rows lock independently, each on its own remote location.
Identity (Mine)
Which of your connected accounts each repo in this project pushes as, for your own runs. One row per repo:
- A repo with no pick of its own shows what it inherits, and pushes as that — the destination's account, your default account on the host, or your ambient git credentials, whichever the project resolves to.
- Override opens a picker of your connected accounts on the project's resolved host. Accounts on any other host aren't offered: an override has to sit on the same host as the destination to be usable, and you need at least one account connected there.
- Commit email is optional per repo. Leave it blank and the account's own default address is used.
- A repo carrying an override names the account it pushes as, and Reset to destination drops it back to what it inherits.
An override applies the moment you save it — it's read ahead of the destination and every tier above it. The rows are yours alone: each of your teammates picks their own account per repo, and nothing you set here changes what anybody else pushes as.
Branching Strategy
Project-level branching defaults. Individual repos (in the Repositories card below) can override each value.
- Branch strategy — what entity a branch represents (story / epic / phase)
- Branch prefix — optional prefix prepended to all story branches
- Story branch template — pattern (e.g.,
feature/{story_slug}) - Epic branch template, Phase branch template — pattern for epic / phase branches when those strategies are in use
Template variables: {prefix}, {slug}, {story_slug}, {display_id}, {release}. A template referencing any other token falls back to {prefix}/{display_id}.
Release branches:
- Release branch prefix — a plain prefix prepended to a slug of the release's name to compose its default branch, e.g.
release/brave-otter— no template variables, just literal text prepended to a slug of whatever name the release settles on. It's a one-time snapshot rather than a live setting: creating or importing a project copies your workspace's own git defaults —release/unless your workspace changed it — straight onto this project's column at that moment, and nothing here reads the workspace again afterwards; a later change to the workspace default reaches this project only through Push to Projects, which overwrites every project's own column with whatever the workspace holds right now. From then on Trinity composes a release's branch from the project's own stored value alone — clear it and a release composes with no prefix at all. That read happens once per release, at the moment it's created without an explicit branch of its own; editing the project's prefix only affects releases created afterwards, because an existing release's branch is a stored fact this setting is never re-read against. A release branch lives for one release: cut at create, and left behind once it ships. - Maintenance branch prefix — the same kind of prefix, for a maintenance line, e.g.
maint/3.x, seeded and pushed the same way: a one-time snapshot of the workspace's own default (maint/unless changed), taken when this project is created or imported and read from its own column alone from then on; only Push to Projects re-syncs it to a later workspace change. Clear the project's own field and a line's branch composes with no prefix at all (1-1-xrather thanmaint/1-1-x) — see Releases → Starting a line. A maintenance branch lives indefinitely: Trinity creates it the first time an old version line gets patched, and reuses it for every patch after. Read once, at that first patch; editing it never moves a line that already exists.
Every release creates a release branch from the project's production branch; stories merge into it instead of straight to production. Whether that branch is cleaned up once the release ships is an automation toggle — General → Automation → Delete release branch after merge. Individual releases can pin their own automation override on the release detail page's automation tab. See Releases → Maintenance lines for how a maintenance line is patched.
Release Defaults
Controls which branches releases route through, how a release promotes by default, and the release policy your repository carries:
- Repository topology — which branch your releases integrate on: Dev line (the default — releases fork from your dev branch, land there first, and ship by fast-forwarding dev onto your base branch) or Single trunk (releases fork from your base branch and merge straight back into it; shipping is the version tag, with no dev hop). New releases stamp their route from whichever shape is set when they're created, so changing this leaves releases already in flight on the route they started. See Releases → Repository topology for what each shape means day to day.
- Default promote mode — the path a release takes by default when you ship it: Ship (through staging), Integrate (straight to your dev branch, stopping there), or Ship Now (the same walk as Ship with the staging gate bypassed). You can still pick a different mode per release in the Promote panel. Set here, it overrides the workspace default for this project.
- Release Policy — first, the policy repo: the repository whose
.trinity/release.jsonreleases read. Moving it is a step of its own — pick a repository, then confirm — and the card warns that the file must exist on the new repository's integration branch (or be saved there from this card after the move), since the file in the old one stops counting and a branch carrying no file releases under the default policy. Then the release groups that file carries: each group's packages, whether they move together on one version (Fixed) or each on its own (Independent), and its tag pattern (any shape likerelease-{major}.{minor}.{patch}; an independent group's pattern names each package through its{package}slot, filled with the package's manifest name when no other package in its repository shares it, else its folder). Below the groups sits the prerelease pointer — the registry dist-tag every labelled release publishes under, whatever its label (defaultnext);latestand each maintenance line's own pointer are derived from what's shipped, never set here. A package no group names versions on its own. Save as a commit commits the file onto your integration branch as you, so the change is reviewable like any other; if the branch moved while you edited, reload and save again. Each branch reads its own copy, so a maintenance line keeps the policy it carries. See Releases → The release policy.
The semver bump (patch/minor/major) is not a setting — Trinity grades it per repository from what changed and you confirm it at the release gate (see Releases → Version bumps). This prefix also applies to the first release that's auto-created when you save your first PRD.
Promotion
These fields control how a release promotes off its branch, and live on the Promotion sub-tab of the Git settings:
- Base Branch — the final production branch a release lands on (default
main) - Dev Branch — the integration branch a release promotes to first, before production (default
dev) - Staging Targets — an unordered set of target branches you can place a release onto ahead of production. Each row is a label + branch; there's no ordering — every target you list is independently available to stage to. Edits collect on screen and land together when you click Save, which is disabled while any row is left with no branch
- Merge Level — how stories batch onto the release branch: directly (
story), or grouped viaepic,phase, orprdbranches. This is the batching granularity, not the merge-commit style — squashing is a separate automation toggle. It is the project's default, and an individual release can override it — one urgent release set tostorygoes straight to trunk, one grouped fix set toepicstages its stories together and lands as a unit. The release's value replaces the project's outright: it neither floors nor caps, soepicon aprd-level project means epic. Whichever value applies, it names the coarsest batch a story may use — a story with no group at that level batches in the nearest group it has, or merges straight to the release branch when it has none. So a story in a loose epic batches on its epic's branch atepic,phase, andprdalike (it has no phase or PRD above it), and a story bare on the release never batches at any level. When the Architect mints a new release it proposes the release's merge level from the shape of the work —epicfor one epic of parallel stories,storyfor a single story — and the release card lets you change it, or leave the release on the project's level. Batching also decides when a dependency clears: within one batch a dependent starts as soon as its upstream's PR lands in the shared branch, but across batches it waits for the upstream's whole batch to merge on to the release branch — the point that code is actually there to build against. So a coarser merge level buys fewer, larger merges and pays for it with dependents that wait longer. See Dependencies
Repositories
Projects can contain one or more git repositories. Each repo shows:
- Name — identifier (e.g.,
web,api,mobile) - Path — relative path from the workspace root
- Production branch — repo-specific production branch (overrides the project default)
- Branch templates — per-repo overrides for branch naming
- Read-only dep — when enabled, Trinity clones the repo so agents can read it but never branches, commits, opens PRs, merges, or tags it. Use this for upstream forks, vendored libraries, or any repo you don't have write access to.
- Staging target overrides — a repo can override the project's Staging Targets list with its own, for the case where one repo in a polyrepo stages to different branches than the rest. Off, it inherits the project's list unchanged; turned on, it starts from that same list for you to edit, and the edits are its own — saved, like the project-level list, through Save.
For monorepos you typically have a single repo entry pointing to the root. For polyrepos each repository gets its own entry.
Collaborators (GitHub)
Manage who has access to your project's GitHub repos directly from Trinity. The card shows each collaborator's avatar, username, and permission level. For polyrepo projects a repo selector lets you switch between repos.
Invite by GitHub username. Permission levels:
| Permission | Access |
|---|---|
| Read | View code and clone |
| Write | Push commits and manage issues |
| Maintain | Manage repo without admin access |
| Admin | Full repository access |
The username field autocompletes from the workspace members' linked GitHub handles.
Trinity also gates its own UI/API actions by your actual GitHub permission level on the repo:
| Your GitHub level | What Trinity lets you do |
|---|---|
| Read | View project, browse plans and stories |
| Write | Run stories, respond to gates, manage collaborators |
| Maintain | All Write actions plus project settings |
| Admin | Full access including danger zone |
This is the forge's answer rather than Trinity's, so it is asked in every workspace: a workspace of one still holds exactly whatever access GitHub granted you on that repo.
AI Models
Model Overrides
Override the global model selection per-tier for this project. Configurable tiers:
- Frontier — the top rung, opt-in only per chat message or per story; overriding it here just changes which model that opt-in resolves to, not when it fires
- Reasoning — complex agent work (planning, story pipeline)
- Standard — default agent tier
- Micro — lightweight / parallel tasks
See AI Model Configuration for the full tier ladder.
Each model saved here has to be one Trinity actually carries — see Only a real model can be saved.
Provider Keys
Provide your own API keys for Anthropic, OpenAI, DeepSeek, Moonshot, Z.ai, Qwen, Xiaomi, xAI, Sakana, or Ollama scoped to this project. Keys are encrypted server-side.
Skills
Manage the skills scaffolded into this project's workspace-trunk .agents/skills/ directory (projected per-harness and overlaid into each story worktree at runtime):
- See which core
trinity-app-*skills are installed - Add skills from the registry
- Re-scaffold skills to refresh them from the templates
Secrets
The Secrets tab is split into three sub-tabs that share the same underlying encrypted store:
- Overview — a glance card with counts ("configured" / "need setup"), a pending-setup list per stack service, and a "Re-sync files" button for materializable rows. Use it to see at a glance what's wired up and what still needs values.
- Shared — package-bound secrets every member can see (cascade tier 3/4). Full table view with search, package filters, bulk
.envpaste import, and per-package editing. - Yours — your personal per-project overrides (cascade tier 1/2). Same editor, scoped to your account; no other member sees these rows.
Pick Shared for keys the whole workspace needs (an API endpoint, a non-secret config value), pick Yours for keys that are only yours to use (your own LLM provider key, your personal storage credentials).
Secrets are end-to-end encrypted: encryption keys are generated and held on your devices, and the server stores only ciphertext it can never read. New devices must be approved from one of your existing devices before they can decrypt anything — manage them in App Settings → Profile → Devices. Cascade resolution at consume time picks package-specific (your personal value over a shared one) → global for the same key — every secret is bound to a package, the codebase directory whose .env it lands in.
Stack
The Living Stack card (its title in-app) tracks every technology decision for this project: frameworks, databases, ORMs, auth providers, architectural tools. Each item can carry a researched pricing badge — free, freemium, or paid, with a short note and a source link — so you can see at a glance what a service costs. Items come from several sources:
| Source | When |
|---|---|
| Onboarding | Technologies chosen during greenfield setup or detected during import |
| Planning | The dependency mapper names the story that installs each item the plan introduces |
| Story | While documenting a story — before it merges — Trinity reads that story's own changes and proposes whatever it added, dropped, or swapped, linked to the story that did it |
| Post-merge | After each story merges, Trinity scans for newly introduced tools and flags them as suggestions |
| Scan | Reads the branch's real dependency files (package.json, requirements.txt, etc.) and flags anything not yet tracked. Runs automatically after every merge as a backstop to Post-merge, and on demand via the "Scan a branch" field for a branch that hasn't merged yet (e.g. checking work-in-progress, or tools added outside Trinity). |
Item Status
An item walks one of two arcs, in and out:
| Status | Meaning |
|---|---|
| Pending Review | A story is declared to add it, but hasn't installed it yet — accept or reject |
| Adding | The story installed it, and is on its way to shipping |
| Active | The story that installed it has shipped — it's really in the codebase |
| Planned Removal | A story is declared to take it out, but hasn't done so yet |
| Removing | The story removed it, and is on its way to shipping |
There's no "Removed" state to look at: once the story that removes an item ships, the item leaves the list. Its history is still on record — Trinity can answer when the project had a piece and which story took it away — but the Stack card shows what the project has and is getting, not a graveyard.
Two actions sit on the rows that are still proposals, and appear on hover:
- Accept / Reject on a Pending Review item — take the proposal or drop it.
- Re-activate on a Planned Removal item — take the removal back. It works right up until the removing story ships; after that the removal is a fact, not a plan, and can only be undone by adding the item again.
Assignment Tracking
Each row shows the story that put the item there — story A3F9K2XQ, by its display ID. An item with no story beside it is one nobody has claimed: something asserted directly at setup or import, or a proposal no story has picked up. Its status badge already says which.
Status is never a flag someone remembered to set — it's worked out from what your stories declared and how far each has actually got. That's why a half-shipped release reads correctly: a merged story's items show Active while its unmerged sibling's still show Pending Review, in the same release, at the same moment. It also means a story that declares an addition and ships without ever installing the piece leaves the row honest — still a plan, not a claim your codebase can't back up.
During planning, the dependency mapper names which story installs each thing the plan introduces. While a story is being documented, anything Trinity finds in that story's own changes is proposed already attributed to it. After execution, the post-merge scanner verifies those attributions and flags mismatches.
Worktrees
View and manage the on-disk git worktrees Trinity uses to run stories in isolation:
- Active worktrees with the story they're assigned to
- Orphaned worktrees (from crashed or killed workers)
- Full history of past worktrees
- Manual cleanup actions
You usually don't need to touch this — Trinity manages worktrees automatically. The tab is there for debugging when something gets stuck.
Danger
Reset Project
Greenfield projects only — imported projects don't show this card. Their repos are your own pre-existing codebase, not something Trinity created, so resetting and recreating them isn't safe. Use Delete instead if you want the project gone.
Reset is a delete-and-recreate cycle. It stops the coordinator, removes worktrees, closes PRs, closes the project's open story issues as not planned, deletes the GitHub repos and the on-disk workspace, and clears the project's sync-DB tables. The next pass through onboarding's Repos step recreates the repos from scratch — same name, same description, fresh history.
Repo deletion goes through Trinity's own REST client under the transport rail's resolved credential — there's no local git/gh binary preflight. The dialog does show a non-blocking warning up front when your connected token is a classic GitHub token confirmed to lack the delete_repo scope (fine-grained PATs can't be introspected this way, so no warning shows for them even if the scope is missing); the dialog embeds a one-click flow to add the scope without re-authing.
The reset dialog has a Delete uploaded assets toggle:
- Trinity Cloud (managed): locked on. Trinity-hosted assets can't outlive the project they belong to.
- BYO S3 / Local Only: defaults to off, so the files you uploaded survive the reset and you can re-attach them. Flip it on to wipe the local cache and asset records too. Objects in your S3 bucket are never deleted by Trinity — only the local-only files and the asset rows pointing at them.
Move Project
Transfer a project to another workspace you belong to. Only the project owner can start a move, and the destination has to be a workspace you are already a member of — the picker offers exactly those, minus the one the project is in now.
All the project's data moves into the destination workspace's database, and Trinity Cloud assets are re-keyed into that workspace's storage. Moving requires typing the project name to confirm; everything else runs automatically — no manual file moves.
A move doesn't carry the member list across — the destination starts fresh and the dialog notes "Roster reset — re-add members in the new workspace." Trinity carries over the git identities the project relies on where it can; members who aren't in the destination workspace can't have theirs follow, and the dialog tells you how many were skipped.
Two things can refuse the move up front. The destination has to have somewhere configured to host repos. And a project on Local Only storage can't simply move: its files live on one machine, so the destination workspace has to have opted into migrating them ("Auto-migrate local storage" in its workspace settings) — otherwise switch the project to Trinity Cloud or BYO S3 first.
Approval workflow: if the workspace the project is leaving requires approval to move projects out, the move files a request instead of executing. Owners and managers of that workspace approve or reject it from their Inbox, which you can reach from any workspace — it renders one section per workspace you belong to, so you can act without switching first. Once approved, the move executes on the requester's next sync. See Workspaces for the policy.
Delete Project
Hard-delete the project. Permanently removes the project row, closes the project's open story issues as not planned, and optionally deletes the GitHub repos (requires the delete_repo scope on the connected token; gh auth refresh -s delete_repo adds it if you connected via the GitHub CLI). The same Delete uploaded assets toggle applies to your FILES — on for Trinity Cloud, your choice on BYO S3 / Local Only — but the asset records themselves always go, because the project they point at is gone. On Reset the toggle governs both, since the project survives and you can re-attach what it kept. Repo deletion goes through Trinity's own REST client under the transport rail's resolved credential — there's no local git/gh binary preflight — and the same non-blocking delete_repo scope warning as Reset applies here; once it succeeds you're redirected to the New Project screen. Requires typing the project name to confirm. Gated by the Delete Projects permission.