Root Folder catalog and metadata definitions
A Root Folder is a canonical, first-class classification record — not free text and not a generic custom field (see Glossary). Every Root Folder has exactly one immutable owner, the member who created it. Custom metadata definitions are the administrator-managed schema behind every --meta key=value a user supplies to tv file put. For definitions of Root Folder, subfolder, tag, archived, deactivation, and admin override, see Glossary.
Root Folders — created and owned by any active member
tv folder create "Finance"
tv folder list
tv folder list <folder-id>
Creating a Root Folder is not an administrator-only action — any active organization member creates and owns their own Root Folders with tv folder create. The caller becomes that folder's immutable owner and immediately resolves manage access to it, with no separate access-grant row ever created for that ownership; nobody else can see or use the new folder until the owner explicitly shares it with tv folder access grant (see Access and delegation). A trimmed name only conflicts (FOLDER_NAME_CONFLICT) with another Root Folder the same owner already has, active or previously deactivated — a retired name stays reserved against its own owner forever so a historical file reference (an audit event, an old tv file info) can never resolve ambiguously against a reused name — but a different owner may freely reuse the exact same name.
tv folder list [<folder-id>] (issue #56) is a browse operation: it returns only the immediate child folders and files of the selected folder, never a recursively flattened subtree — descend one level at a time by re-running it with a child folder's ID. Omitting <folder-id> browses the caller's own default Root Folder ("My Files"). Entries are a stable, minimal, typed page — kind (folder/file), ID, name, status, an owner-safe projection, and timestamps — never file bytes, signed URLs, hidden tags/typed metadata, grants, or full audit history. Results order active folders first, then active files, each group by normalized name then ID; add --include-archived to also see archived entries. Large folders page with a bounded --limit and an opaque --cursor -- the identical keyset-pagination pattern tv file find uses (see Command reference) -- never an offset. An ordinary caller sees only what they may access; a folder ID that is hidden from them and one that genuinely does not exist return the identical anti-enumerating NOT_FOUND, and an administrator (admin/global_admin) instead browses any folder in the organization unconditionally, with every such call recorded as its own audited admin.content.access event.
tv folder list deliberately stops at one level; when you instead need every file anywhere beneath a folder in one search, tv file find --within <folder-id> (issue #57) is the recursive counterpart -- it matches the start folder plus every descendant, computed fresh from the current hierarchy on each call, so a folder moved into or out of the subtree changes the results immediately. It composes with every other tv file find filter and stays access-filtered and anti-enumerating exactly like browse: a hidden or nonexistent start folder both fail with the identical NOT_FOUND, and an administrator's subtree search is unconditional, audited as its own admin.content.access event only when the override actually applied. See Command reference and Search and discovery.
Because tv folder list with no argument now shows your default Root Folder's contents rather than every Root Folder you own or have been granted, there is no single command left that enumerates every Root Folder an ordinary member can reach — a Root Folder shared with you that is not nested under your own default root is reached by browsing to it directly with the ID the granter shared out of band (for example, from their own tv folder create/tv folder access grant output), not by discovery. tv admin folder list below remains the separate, administrator-only, organization-wide catalog surface (every Root Folder regardless of owner, status, or grant, including deactivated ones) — it is a flat catalog, not the same operation as the unprivileged browse above.
The default Root Folder ("My Files")
Every active member automatically has exactly one default Root Folder, named "My Files" the first time it is provisioned. It is created idempotently -- never as a separate command a member runs -- at whichever moment first makes that member active: bootstrap, invitation acceptance, or reactivation after a prior deactivation. A structural partial unique index (one row where is_default is true per member) guarantees at most one default even under a retried or genuinely concurrent first login; a deactivated member is skipped by that provisioning and receives no new folder until they are reactivated, at which point it is retried, still exactly once. Backfilling every already-active member follows the identical rule and never repurposes an existing Root Folder into the default -- provisioning only ever adds a brand-new row and never touches a member's other Root Folders.
tv folder list
tv file put report.txt
Bare tv folder list browses this default Root Folder's own immediate contents (see above), so the freshly bootstrapped example above is empty until something is created or uploaded into it. tv folder create, tv folder rename, tv folder move, tv folder archive, tv folder restore, and tv admin folder list all still return a full FolderRecord for the folder(s) they act on or catalog, and mark the default one with (default) in human output and isDefault: true in --json; the minimal browse entries tv folder list now returns carry no isDefault field at all (see above) since a default Root Folder, being a root, never appears as someone else's child entry anyway. The default identity is the flag (and the owning member), never the display name -- the owner may freely rename it with any Root Folder rename path available to them, and it stays the default under the new name. It is private to its owner exactly like any other Root Folder until explicitly granted with tv folder access grant (see Access and delegation), and ownership transfer remains unsupported, so the default can never move to a different member. tv file put <path> may omit --folder entirely, in which case the upload resolves to the caller's own default Root Folder -- never another member's, and never any Root Folder the caller does not already own or manage. No other command infers a folder this way; every other --folder-accepting command still requires it explicitly.
The default Root Folder is a root like any other: it may itself gain subfolders through --parent below, and nothing about being the default changes that.
Nested subfolders
tv folder create "Finance" --parent 11111111-1111-4111-8111-111111111111
tv folder create "2026" --parent 22222222-2222-4222-8222-222222222222
Any Root Folder -- a root or an existing subfolder -- may gain child subfolders through tv folder create <name> --parent <folder-id>. Every folder resolves an immutable rootFolderId (equal to its own ID for a root) and a depth (0 for a root), so boundary checks never walk the full ancestor chain. Nesting is capped at depth 32 (root plus 32 nested levels); creating a child beneath a folder already at depth 32 fails with the dedicated FOLDER_DEPTH_EXCEEDED code rather than a generic conflict. A subfolder's owner is always its root's owner -- ownership does not change part-way down a tree -- while the member who actually ran the command is recorded separately as the creator for audit purposes.
Creating a subfolder requires live manage access to the immediate parent; read or write access is not enough, and losing or gaining manage (see Access and delegation) takes effect on the very next command, with nothing cached client-side. A parent that does not exist, belongs to a different organization or root tree, or that the caller cannot manage all produce the identical anti-enumerating FOLDER_PARENT_NOT_FOUND -- a caller can never distinguish "no such folder" from "you may not use that folder" by probing IDs. Sibling names beneath one parent are trimmed and unique case-insensitively among active and deactivated children of that same parent (the existing FOLDER_NAME_CONFLICT code, not a new hierarchy-specific one); a different parent, or the organization-wide root level, may reuse the same name freely. A root cannot be re-parented into becoming somebody's child through this creation surface, and creating a subfolder never touches any file version, storage key, or access grant -- it is audited purely as its own folder-creation event, carrying the new folder's parent, root, and correlation ID as evidence.
Access inherits down the whole tree
A grant made on any Root Folder or subfolder applies to that folder, every descendant folder beneath it, and every file contained anywhere in that subtree (issue #55) -- there is no need to re-grant separately at each nesting level. manage, wherever it says "live manage access" above, is resolved the same way: ownership, a direct grant, a group grant, or a grant on any ancestor folder, whichever is highest, evaluated fresh on every call. See Access and delegation for the full authority model, the owner-and-subtree delegation bound, and how a move or revocation takes effect immediately throughout an affected subtree.
Root Folders — administrator visibility and deactivation
tv admin folder list
tv admin folder list --folder 11111111-1111-4111-8111-111111111111
tv admin folder deactivate "Finance"
There is no tv admin folder update — an administrator can never edit a Root Folder's name or other classification directly; only its active/deactivated status can change, and that remains administrator-gated. The owner (or a manager) renames it themselves with tv folder rename below. tv admin folder deactivate is idempotent and never deletes the row — every file, grant, and audit reference to that Root Folder keeps resolving correctly after deactivation. The one exception is a member's own default Root Folder ("My Files"): it cannot be deactivated while it remains the default (DEFAULT_FOLDER_PROTECTED), so every member is guaranteed somewhere to upload without an administrator being able to remove it out from under them. tv admin folder list is the separate administrator surface that shows every Root Folder in the organization regardless of owner or status, active or deactivated, without needing any grant on it (issue #55); the optional --folder <folder-id> narrows the response to exactly that one folder row (not an implicit subtree -- list once per folder ID, or omit the flag for the full organization-wide dump and filter client-side). tv folder list <folder-id> (unprivileged, browsing one folder's immediate children -- see above) works differently: an administrator calling it browses that folder unconditionally, with no grant needed, exactly like tv file info/tv file get's administrator override -- it is still bounded to one folder at a time, never the organization-wide flat catalog tv admin folder list provides. Every browse call is itself an audited admin.content.access event (details.operation: "list_folders"), recorded with the organization-bound adminOverride evidence described in Audit and administration.
Renaming, moving, archiving, and restoring Root Folders
tv folder rename 11111111-1111-4111-8111-111111111111 "FY26 Finance" --reason "annual rename"
tv folder move 55555555-5555-4555-8555-555555555555 --parent 66666666-6666-4666-8666-666666666666 --reason "reorg"
tv folder archive 77777777-7777-4777-8777-777777777777 --reason "project closed"
tv folder restore 77777777-7777-4777-8777-777777777777 --reason "reopened"
All four commands key by folder ID (never by name, since names are not globally unique) and require an explicit, non-empty, render-safe --reason bounded to 500 characters — a missing --reason is a local usage error, never a network call. Each requires live manage access on every folder it touches and re-evaluates that access fresh on every call, exactly like creation above; a folder the caller cannot manage produces the identical anti-enumerating NOT_FOUND a nonexistent one would.
Rename reuses the same case-insensitive sibling uniqueness tv folder create enforces, including reservation of a retired (archived) sibling's name — renaming into a name an archived sibling still holds fails with FOLDER_NAME_CONFLICT, just as creating one would.
Move relocates a subfolder to a new parent within its own root only; a root itself can never be moved (FOLDER_ROOT_IMMOVABLE). Move additionally requires live manage on the folder's current parent as well as its new one, so a delegate who only manages the folder and its destination — not where it lives today — is still denied. Self-parenting and making a folder the child of its own descendant both fail as FOLDER_CYCLE_DETECTED; a target outside the folder's own root fails as FOLDER_CROSS_ROOT_MOVE; a target that would push the folder past depth 32 fails as FOLDER_DEPTH_EXCEEDED. Every one of these checks runs before any row changes, so a rejected move leaves the tree exactly as it was. A successful move never touches a file's ID, version, metadata, access grant, or storage key anywhere beneath it, and immediately changes who can manage the moved subtree with no cached decision from before the move. Two concurrent moves of the same folder serialize rather than corrupt each other's result; whichever commits last decides the final parent.
Archive is allowed only when the folder currently holds zero files and zero child folders, active or archived — an archived child folder or an archived file still counts, so a folder is only ever empty by never having held content, or by moving that content elsewhere first (tv file move for a file; tv folder move for a subfolder, within the same root). Because a subfolder can never leave its own root, a root that has ever had a subfolder created under it can never become archivable again, even after every descendant is itself archived. The default Root Folder can never be archived, matching the deactivation rule above (DEFAULT_FOLDER_PROTECTED).
Restore is always explicit — nothing ever restores a folder automatically — and additionally requires every folder in its parent chain to currently be active; a folder whose parent (or a more distant ancestor) is deactivated or archived fails with FOLDER_PARENT_INACTIVE. A root has no parent, so restoring one never depends on anything but its own state. Archiving an already-archived folder, and restoring an already-active one, both succeed as no-op idempotent calls rather than errors.
No hard-delete command or route exists for a Root Folder at any point in this lifecycle — archive is the only irreversible-looking state, and it is always explicitly reversible. Every rename, move, archive, and restore call is recorded as its own append-only audit event carrying the before/after name, parent, or status, the acting user, the supplied reason, and the correlation ID.
Metadata definitions
tv admin metadata create due-date --label "Due Date" --type date --required
tv admin metadata create priority --label Priority --type choice --choice low --choice medium --choice high
tv admin metadata list
tv admin metadata show due-date
tv admin metadata update priority --add-choice urgent --remove-choice low
tv admin metadata deactivate due-date
A definition's key and --type (text, number, boolean, date, or choice) are fixed forever at creation — tv admin metadata update accepts no --type flag at all. Only --label, --required, and — for a choice field — its allowed-value set may change later. --choice/--add-choice values are trimmed and de-duplicated automatically. Narrowing a choice field's allowed values (--remove-choice) does not retroactively invalidate files that already carry the removed value; they keep failing re-validation as FILE_METADATA_INCOMPATIBLE only if someone tries to re-set that field, which forces them onto a currently-allowed value. tv admin metadata deactivate is idempotent and never deletes the definition. tv admin metadata list/show reveal every status (including deactivated) to an administrator; the unprivileged tv metadata list shows active definitions only.
Why the model differs between Root Folders and metadata
Tags — user-managed, no administrator schema (issue #58)
Tags are a deliberately separate, permanent name=value model from the metadata definitions above: any file owner or delegate with write/manage access sets and removes their own tags with tv file tag set/unset (see Working with files) with no administrator setup at all -- no schema, no type, no tv admin tag command family. The two systems never share storage or rows: a tag never appears in tv file info's metadataValues, and a metadata field is never something a user free-types a value for the way a tag is.
An administrator gets the identical unconditional override this page already documents for folders/files above: tv file tag set/unset/list succeed on a file the administrator holds no grant on, always recorded as its own audited admin.content.access event. There is no separate tv admin tag visibility surface, because ordinary tv file tag list combined with the administrator override already covers it -- unlike metadata definitions, which need one because their schema itself is administrator-owned.
tv file find --tag <name>[=<value>] (issue #59) is how a user locates tagged files -- there is no separate administrator tag-search surface, because an administrator's tv file find already searches the whole organization unconditionally (see Command reference). Tag filters AND-compose with --within and every other search filter, are index-backed (no JSON or application-side scan), and re-evaluate live: a tag set or unset changes search results on the very next call. A hidden file's tags never affect a visible result count -- authorization is applied before the tag predicate, exactly like every other search filter on this page.
Metadata definitions stay a strictly administrator-managed schema: ordinary users can only ever read the metadata catalog (tv metadata list) so they can populate tv file put --meta key=value correctly without guessing the right key, type, or allowed values — they can never create, rename, or retire a metadata field themselves. A single organization-wide field schema keeps every file's custom metadata consistent without turning every upload into a schema negotiation.
Root Folders work differently on purpose: any active member creates and owns their own Root Folders (tv folder create), and only an administrator retires one (tv admin folder deactivate) or sees every Root Folder in the organization regardless of owner (tv admin folder list). Ownership, not administrator status, decides who may use, share, or see a given Root Folder day to day.
Continue with Users, roles, and groups or Audit and administration.