Skip to main content

Org Working Tabs Lifecycle Spec

Status and authority

This document is the product source of truth for the organization topbar working-item rail and every resumable dialog lifecycle that participates in it. It defines the intended behavior before implementation begins.

The supporting documents have different jobs:

Purpose

Working tabs let a person begin or inspect work, temporarily leave it to find information elsewhere in the app, and resume exactly where they stopped.

The rail is a stable workbench, not navigation history:

  • genuinely new work is added at the front
  • existing work never jumps around merely because it was viewed again
  • meaningful or deliberately pinned work survives being hidden
  • a lifecycle keeps the same place as it moves from create to saved preview or between preview and edit
  • discarding a draft and removing a saved shortcut are deliberate actions

This is the default behavior for all core organization work surfaces. A feature may differ only when its product semantics require it and the exception is documented in this specification and in the lifecycle audit.

Vocabulary

TermMeaning
Working itemOne entry in the topbar rail representing a resumable unit of work
LifecycleThe continuous identity of that work across create, saved preview, edit, and related stages
StageThe current surface within a lifecycle, such as create, preview, edit, or a parent-owned operation
Lifecycle IDStable identity for an unsaved lifecycle
Canonical record IDSaved record identity, expressed conceptually as record type plus record ID
Added orderImmutable sequence assigned only when a lifecycle genuinely enters the rail
ActiveThe working item's surface is currently visible
HiddenThe item remains resumable in the rail but its surface is not visible
EngagedThe person has entered meaningful work or otherwise begun a task that must remain resumable
DirtyCurrent draft differs from its most recently persisted baseline
PinnedThe person explicitly chose to retain the lifecycle in the working rail
HandoffAn identity-preserving transition, such as create draft to saved record
RemoveTake the lifecycle out of the working rail without deleting a saved record
DiscardIntentionally abandon unsaved changes or an unsaved lifecycle

engaged and dirty are intentionally different. Autosave may make an engaged draft clean, but it must not make the working item disappear. Dirty state controls save and discard warnings; engagement is a retention reason.

Non-negotiable product invariants

  1. A newly added lifecycle appears as the first working item after permanent shell controls.
  2. Each lifecycle receives one immutable added order.
  3. Viewing, resuming, hiding, editing, pinning, unpinning, saving, autosaving, or changing a lifecycle stage never changes that order.
  4. A create-to-record or preview-to-edit handoff keeps the same working item and the same position.
  5. Opening a lifecycle that is already in the rail activates the existing item. It neither duplicates nor reorders it.
  6. Removing a lifecycle ends that rail membership. Adding it again later is a genuinely new addition and therefore places it first.
  7. An empty, unpinned create that is hidden or cancelled disappears as though it was never opened.
  8. Pinning an empty create immediately creates a retainable draft lifecycle, even before any field is changed or autosaved.
  9. Meaningful unpinned work remains resumable when hidden.
  10. Pin state belongs to the lifecycle, not to a single dialog component or stage.
  11. Successful create handoff is atomic: the unsaved and saved identities never render as two working items.
  12. Navigation within the organization app cannot destroy a retained lifecycle or replace its exact draft with a generic preview.
  13. Failed saves leave the lifecycle, stage, pin state, draft, and position unchanged.
  14. Removing a saved record from working tabs never deletes the underlying record.
  15. Organization and user scope are strict. Working state must never leak to a different organization or signed-in person.

Stable insertion order

Ordering rule

The visual order is newest genuinely added lifecycle first. It is not based on the last item viewed, focused, updated, saved, autosaved, or pinned.

Conceptually, the rail sorts only by an immutable addedOrder. Fields such as lastViewedAt, updatedAt, savedAt, or pinnedAt may support other product needs, but they must never decide working-tab position.

The added order persists for as long as the lifecycle remains retained. It survives hide/resume, refresh, draft recovery, and create-to-record handoff. For durable saved pins it also survives cross-device loading; synchronizing a pin must not assign it a new position merely because another device read or updated it.

Events that create a new position

  • opening a new create lifecycle
  • opening a saved record that is not already represented
  • starting a separate quick-note lifecycle
  • starting an independent nested record lifecycle
  • pinning a saved record that is not already in the rail
  • re-adding a lifecycle after it was explicitly removed

Each is inserted first.

Events that preserve the existing position

  • clicking or focusing an existing working tab
  • reopening the same record from a route, list, search, notification, or link
  • hiding and later resuming a dialog
  • pinning or unpinning an existing working item
  • typing, validation, autosave, or explicit save
  • create-to-record handoff
  • preview-to-edit or edit-to-preview transition
  • a title, status, permission, or other metadata update
  • a child dialog returning to its parent stage

Canonical example

  1. A project create lifecycle is added and pinned.
  2. Saving changes that same working item into the project preview. Its position does not change.
  3. A new note is added afterward. The note is now before the project.
  4. The person clicks the project working tab again.
  5. The project opens, but the note remains before it.

The rail therefore reflects when work joined the workbench, not what the person looked at most recently.

Removal and re-addition

If the project in the example is removed from the rail and later opened or pinned again, that later action creates a new rail membership. It receives a new added order and appears first.

Lifecycle state model

Every core working item must be representable by one shared lifecycle shape, regardless of which feature renders it.

PropertyProduct meaning
Lifecycle identityStable identity before save and across all unsaved stages
Canonical identityOptional until a record exists; stable after handoff
Current stageCreate, preview, edit, or a documented parent-owned stage
Added orderImmutable position token for this rail membership
VisibilityActive or hidden
Pin stateExplicit retention selected by the person
EngagementWhether meaningful work has begun
Dirty stateWhether unsaved changes differ from the persisted baseline
Persistence scopeMemory, browser session, same-device durable draft, or backend durable pin
Parent relationshipOptional owner when a substage belongs to another lifecycle

Features may store additional draft or view data, but they must not invent independent ordering, pinning, or close semantics.

Retention rules

A working item remains in the rail while at least one retention reason applies:

  • its surface is active
  • it is engaged
  • it is pinned

Dirty state is evidence of engagement but is not the only form of engagement. For example, a successful background autosave can make a draft clean while the person still expects to resume it.

Successful explicit completion is different from autosave. When the default flow says a completed unpinned create or edit closes, that completion consumes the temporary engagement reason and hides the surface. Pinning is the explicit choice that carries the lifecycle into its saved preview stage.

State when hiddenRequired result
Empty, unpinned createRemove immediately
Empty, pinned createKeep as a hidden draft
Engaged, unpinned createKeep as a hidden draft
Engaged, pinned createKeep as a hidden draft
Clean, unpinned saved previewRemove its temporary rail membership
Pinned saved previewKeep
Existing-record edit with meaningful workKeep the exact edit stage, pinned or not
Existing-record edit with no meaningful work and unpinnedRemove on explicit close; hide behavior may keep it only for the current active session
Active timer or equivalent server-backed workKeep according to that feature's active-work lifecycle

An unpinned engaged draft may be subject to a documented abandonment policy, but it must never disappear merely because autosave ran or the user navigated away. A pinned lifecycle is never silently expired.

Opening and activation

New create

Opening a create action:

  1. creates a lifecycle
  2. adds it first in the working rail
  3. opens its dialog immediately
  4. begins empty, unpinned, unengaged, and active

Merely registering the tab without showing the dialog is invalid.

Existing saved record

Opening a saved record that is not in the rail:

  1. creates one temporary record lifecycle
  2. adds it first
  3. opens its requested preview or edit stage

Opening a saved record already represented in the rail activates that same lifecycle and requested stage without changing its position.

Duplicate entry points

Routes, collection rows, search results, notifications, quick views, and topbar tabs must resolve through the same canonical lifecycle identity. Concurrent or repeated opens must not produce duplicates.

Dialog dismissal semantics

Controls must describe their effect consistently. “Hide” and “discard” are not synonyms.

Pointer outside, Minus, and Escape

These are non-destructive hide or minimize actions:

  • the surface becomes hidden
  • retained state remains exactly resumable
  • an empty, unpinned, unengaged create is removed because it has no retention reason
  • dirty or pinned state is never discarded

If a particular modal must disable pointer-outside or Escape dismissal while a critical operation runs, those gestures do nothing. They must not be converted into discard.

Dialog X and Cancel

For create and edit stages, dialog X and Cancel express an intent to cancel the current draft or edits:

  • empty, clean, unpinned work can be removed immediately
  • dirty or pinned unsaved work requires confirmation before discard
  • confirming discard removes the unsaved lifecycle, or abandons the edit stage according to the saved-record rules
  • declining returns to the unchanged dialog

For a read-only saved preview, X or Cancel only hides the preview. A pinned record remains in the rail; an unpinned clean preview loses its temporary rail membership.

The UI may offer a separate Minus control specifically to make the hide-versus-cancel distinction obvious.

Topbar tab X

The X on a working tab means “remove from working tabs”:

  • an empty unsaved lifecycle is removed
  • a dirty, engaged, or pinned unsaved lifecycle requires confirmation because removal would also discard its resumable draft
  • a clean saved record is removed or unpinned without deleting the record
  • a saved record with unsaved edits requires confirmation before those edits and the rail membership are removed

Confirmation copy must name the actual consequence. It must never imply that removing a saved working tab deletes the underlying project, note, invoice, file, event, or other record.

Pin behavior

The dialog pin means “keep this in working tabs.”

Selecting pin

  • applies immediately to the current lifecycle
  • does not wait for a successful save
  • retains an untouched create by creating its draft identity and persistence shell
  • follows the lifecycle through every later stage
  • does not change the item's added order or visual position

Clearing pin

Unpinning removes one retention reason; it is not a close operation:

  • an active item stays active
  • a hidden engaged item stays temporarily resumable
  • a hidden clean item with no other retention reason may be removed
  • unpinning a saved record does not delete it
  • unpinning never changes order while the item remains

Visual and accessible state

The pin control must:

  • occupy a consistent dialog-header position where the surface supports working tabs
  • expose a localized accessible name
  • use aria-pressed or an equivalent programmatic selected state
  • communicate pinned state through more than color alone
  • never appear when the feature cannot honor the pin lifecycle

Create lifecycle

Empty and untouched

ActionUnpinnedPinned
Pointer outside, Minus, or EscapeRemoveHide and retain
Dialog X or CancelRemoveConfirm discard, then remove if confirmed
Topbar XRemoveConfirm discard, then remove if confirmed

Meaningful work entered

ActionUnpinnedPinned
Pointer outside, Minus, or EscapeHide and retainHide and retain
Dialog X or CancelConfirm discardConfirm discard
Topbar XConfirm discard and removeConfirm discard and remove
Background autosaveKeep; update baseline onlyKeep; update baseline only

Successful explicit save

For an unpinned create, successful explicit save completes the task and removes the create working item by default. It clears the completed create stage's temporary engagement retention. The saved record remains available through its normal feature surface.

For a pinned create:

  1. the save creates the canonical record
  2. the same lifecycle receives the canonical identity
  3. its stage becomes the saved record preview, unless the feature has a documented post-save stage
  4. pin state remains selected
  5. added order and visual position remain unchanged
  6. the unsaved alias disappears atomically

There must never be a frame or persisted state containing both the create item and its saved-record replacement.

Failed save

Validation or server failure leaves the existing lifecycle visible with its draft, pin state, engagement state, stage, and order unchanged. Errors are shown in the owning surface. A failed save is never treated as completion.

Background autosave

Autosave persists recovery data; it does not complete the person's task. Therefore it:

  • does not close or hide the dialog
  • does not remove the working item
  • does not reorder the item
  • may clear dirty state while engagement remains true
  • must not trigger a saved-record handoff unless the product action truly created the canonical record

Saved preview and edit lifecycle

Preview and edit are stages of one saved-record lifecycle.

  • Preview to edit keeps identity, pin, and position.
  • Edit save updates the same record and lifecycle.
  • Hiding a retained edit must restore the exact draft and substage, not a fresh generic preview.
  • Opening the same record elsewhere activates this lifecycle instead of creating another preview or edit item.
  • A pinned edit remains a pinned saved record after save.
  • An unpinned edit that the person explicitly completes may close and leave the rail by default.
  • A background save does not imply explicit completion and must not remove an engaged edit.
  • Cancelling edits may return a pinned saved item to its clean preview stage; it does not unpin the record unless the person explicitly removes or unpins it.

Nested and parent-owned dialogs

Nested work falls into one of two categories.

Independent child record

If the child creates or edits a separately resumable record:

  • the parent lifecycle remains retained in its original position
  • the child receives its own lifecycle and is inserted first
  • the child's pin and save behavior are independent
  • completing or cancelling the child restores the parent surface without reordering the parent
  • parent draft state and focus context remain intact

Example: starting a new note from a timer creates a note lifecycle while the timer lifecycle remains available.

Parent-owned stage

If the child is only an operation within the parent record:

  • it does not create an unrelated working tab
  • the parent's current stage changes
  • the parent keeps its identity, pin, and order
  • hiding and resuming restores that substage when meaningful work would otherwise be lost
  • completion or cancellation returns to the appropriate parent stage

Examples include a return-reason workflow for a time entry or a relationship configuration stage owned by a client or portal lifecycle.

Transient confirmations launched from either category never become working items.

Identity, deduplication, and handoff

Unsaved identity

Every create or independent quick-note session receives a unique lifecycle ID. Two intentionally separate create drafts of the same type remain separate working items.

Saved identity

A saved record has one canonical working identity for the organization and viewer. Preview, edit, and route variants resolve to it.

Handoff

Create save maps the lifecycle ID to the new canonical record identity while preserving its added order. All rail, dialog, pin, and persistence consumers must observe the transition as one atomic lifecycle update.

Rare identity collision

A truly new create should not collide with an existing canonical record. If an import, retry, or reconciliation does produce two aliases for the same record, the UI must merge them deterministically and retain only one. Prefer the already-established canonical lifecycle and its stable position; never show two tabs or silently discard unsaved content.

Persistence and recovery

Persistence level follows the kind of state:

StateRequired scope
Active visibilityCurrent app runtime
Temporary clean saved-record tabCurrent browser tab/session
Engaged unpinned create or edit draftSame user, organization, and device
Pinned unsaved draftSame user, organization, and device; no silent expiry
Pinned saved recordDurable backend preference, available across devices
Active server-backed work such as a running timerDurable feature state

Cross-device unsaved draft synchronization is not required unless a dedicated backend draft system is introduced. The UI must not imply cross-device recovery for locally stored drafts.

All persisted working state must:

  • be scoped by organization and authenticated user
  • wait for scope resolution before reading or rendering private content
  • survive navigation within the same organization
  • tolerate refresh and browser restart at the level promised above
  • use versioned storage with safe migration
  • reject or quarantine malformed or stale data without deleting valid siblings
  • clear inaccessible record shortcuts after authorization is resolved
  • avoid exposing one user's draft after sign-out or account switching

Unpinned abandoned drafts may have a documented cleanup period. Cleanup must never silently evict pinned drafts, dirty edits, or active server-backed work. If the rail has a capacity limit, it must ask the person to resolve retained items instead of evicting them.

Exceptional and failure states

Save in progress

Duplicate submission is prevented. Hide behavior may be temporarily disabled when required for correctness, but the item remains in place and retains pin state.

Offline or interrupted request

Recoverable draft data remains local. The lifecycle does not hand off until the server confirms the canonical record. Retry cannot create a duplicate working item.

Record deleted elsewhere

The working item shows an unavailable/deleted state, preserves unsaved local edits for recovery where safe, and offers an explicit removal path. It does not silently redirect to another record.

Permission revoked

After authorization resolves, protected record data is removed from view. Any safe local recovery or discard choice must avoid leaking inaccessible server data. The rail does not continuously retry or reorder the failed item.

Multiple browser tabs or version conflict

Conflict handling belongs to the owning feature, but resolving, reloading, or saving a conflict never changes rail order. A backend pin update must not use a record's general updatedAt as its position.

Unsupported or temporarily unavailable adapter

Persisted work is not discarded. The working item may show a recoverable “temporarily unavailable” state until its renderer or migration is available.

Scope by dialog class

Core working lifecycles

The standard applies to:

  • all shell create actions and meaningful quick-note sessions
  • saved-record previews and editors
  • active timer and time-entry transitions
  • independently resumable nested record work
  • parent-owned stages whose state would otherwise be lost during navigation

The complete, feature-by-feature set is maintained in the dialog lifecycle audit. Every row marked Core must adopt this specification. Every row marked Parent stage inherits the owning lifecycle unless the audit explicitly promotes it to an independent record.

Transient dialogs

Confirmations, destructive alerts, authentication/security prompts, secret reveal acknowledgements, and other bounded decisions do not enter the working rail. They remain attached to their owning action.

Shell utilities

Search, launchpad, client focus, changelog, hotkeys, feedback, and similar shell utilities do not become working items. Selecting a real record from a utility opens or activates that record's lifecycle.

Settings and administration

Settings-local and administration dialogs are excluded by default. They join the working rail only through an explicit product decision documenting why the operation must be resumable across org navigation.

Accessibility and interaction requirements

  • Every dialog has an accessible title.
  • Icon-only Pin, Minus, X, and other controls have localized accessible names.
  • Pin exposes a programmatic pressed state.
  • Active, pinned, engaged/unsaved, error, and unavailable states are not communicated by color alone.
  • Keyboard activation matches pointer activation.
  • Escape follows the same non-destructive hide rule when dismissal is enabled.
  • Focus returns to a sensible trigger or destination when hiding, cancelling, or completing work.
  • Resuming restores useful focus within the surface without changing rail order.
  • Confirmation focus is trapped and returns to the unchanged draft when the person declines.
  • Overflow and horizontal scrolling preserve the stable item order.

Acceptance scenarios

These scenarios are release requirements for the shared lifecycle and every applicable core feature.

  1. WT-01 — Untouched unpinned create: Open Create Project. It appears first and opens. Click outside. The dialog and working item disappear.
  2. WT-02 — Untouched pinned create: Open Create Project and select Pin without typing. Click outside or Minus. The dialog hides and its working item stays. Resume it and see the same empty draft with Pin selected.
  3. WT-03 — Meaningful unpinned create: Type into an unpinned create and click outside. It hides but remains resumable. Background autosave does not remove it.
  4. WT-04 — Explicit dirty cancel: Use dialog X or Cancel on a meaningful create. Discard confirmation appears. Declining preserves everything; confirming removes the lifecycle.
  5. WT-05 — Pinned create handoff: Pin a create, save it, and observe one pinned saved preview in exactly the create item's former position.
  6. WT-06 — Unpinned create completion: Save an unpinned create explicitly. Its working item closes by default and no duplicate saved preview appears.
  7. WT-07 — Stable project/note order: Pin and save a project. Add a note afterward. The note is before the project. Resume the project; the order does not change.
  8. WT-08 — Existing item activation: Open the same saved record from a route, list, search result, and its working tab. There is one lifecycle and it never moves.
  9. WT-09 — Remove and re-add: Remove a saved record with the topbar X. Open it again. It is a new rail addition and appears first without deleting the record.
  10. WT-10 — Preview/edit continuity: Open a preview, enter Edit, hide it, navigate, and resume. The exact edit draft returns in the original rail position.
  11. WT-11 — Pin during edit: Pin an existing edit, save, and return to preview. The lifecycle remains pinned and stationary.
  12. WT-12 — Unpin without close: Unpin an active item. It remains open and stationary. Hiding it applies normal engagement retention rules.
  13. WT-13 — Nested independent create: Start a note from a retained timer or project. The note is inserted first; the parent stays in its original position and resumes unchanged afterward.
  14. WT-14 — Parent-owned substage: Open an operation belonging to a saved record. No second unrelated tab appears, and the parent does not move.
  15. WT-15 — Failed save: Force a validation or server error. Draft, pin, stage, visibility, and position remain unchanged.
  16. WT-16 — Topbar X on saved record: Remove a pinned saved item. The shortcut disappears only after any required confirmation; the underlying record remains.
  17. WT-17 — Autosaved engagement: Type, allow autosave to clear dirty state, then hide. The engaged item remains.
  18. WT-18 — Organization isolation: Switch organizations or users. No label, draft, pin, or preview from the previous scope appears.
  19. WT-19 — Refresh recovery: Refresh with an engaged or pinned draft. It returns in the promised scope and stable order.
  20. WT-20 — No silent eviction: Fill any working-item limit with retained work. The app never silently removes pinned, dirty, engaged, or active items.

Feature compliance checklist

For every Core row in the lifecycle audit, implementation is incomplete until the applicable checks pass:

The shared default implementation now satisfies the lifecycle-level checks below. Individual feature-owned draft codecs retain their feature-specific validation and recovery responsibilities.

  • new lifecycle opens immediately and is inserted first
  • existing lifecycle activation does not reorder it
  • stable added order survives stage changes and handoff
  • untouched unpinned hide removes the lifecycle
  • Pin retains an untouched lifecycle immediately
  • meaningful unpinned hide retains the exact draft
  • autosave preserves engagement
  • pointer outside, Minus, and Escape are non-destructive
  • dialog X and Cancel use the correct discard semantics
  • topbar X removes working state without deleting saved data
  • pinned create save hands off atomically
  • preview and edit deduplicate to one saved lifecycle
  • navigation and refresh preserve the promised persistence tier
  • nested work preserves its parent identity
  • save failure is lossless
  • organization, user, and authorization scope are enforced
  • keyboard and screen-reader behavior is covered

Implementation readiness requirements

Implementation should not begin as isolated per-dialog patches. The shared design must first provide:

  1. one lifecycle/event model for ordering, retention, pinning, handoff, and removal
  2. one immutable cross-owner added-order mechanism
  3. one adapter contract for create, preview, edit, quick-note, timer, and parent-stage renderers
  4. one canonical identity and deduplication path for saved records
  5. versioned migration from existing create, quick-note, temporary-tab, edit-tab, and durable-pin stores without losing valid work
  6. feature-by-feature tests derived from the audit and acceptance scenarios

Implementation details may evolve, but they may not weaken the behavior in this specification.

Explicit non-goals

  • The rail is not browser history or a list of most recently viewed records.
  • Activating an item does not move it to the front.
  • Pinning is not a favorite/star system and does not change feature-level starred state.
  • Transient confirmations and security prompts are not resumable work.
  • Unsaved drafts are not promised across devices without a dedicated backend draft system.
  • Removing a working tab never means deleting its saved record.