NEXT predates the access work, so the identity layer follows master: access comes from configured groups, instance administrators replace the site administration, and accounts are created by SSO or by an administrator. Kept from NEXT: manual publication with the Review changes panel and shared generator drafts, portable import/export (meguri/v2), the layered generation map with binding provenance, JSM provider changes, contact/approval semantics and the account-owned Person. Dropped: site administration, local sign-up, and the mandatory unique email with its contact/account migrations. The manual-publication migration is renumbered m_0010 after m_0009_access. Accounts without an email still get a Person in every workspace they reach, a changed sign-in email updates the account's person, and an account that loses access keeps its linked person so schedules stay valid. Instance administrators may use Sync and shared drafts. Co-Authored-By: Claude <noreply@anthropic.com>
36 KiB
Test architecture
The daily cover workflow has a PostgreSQL regression for read-only preview, volunteering, owner approval, denied self-approval/third-party transfers, force permissions, empty comments and current-interval clipping. tests/browser-cover.cjs creates its own workspace and checks calendar → offer → owner acceptance, own-day request → exact-request acceptance, the privileged third action without a comment, early range errors, comment visibility, display timezone and mobile layouts. Browser navigation opens Setup explicitly; daily flows do not need it.
Scheduling errors are product failures. A change to ownership, time boundaries, approvals, access, or synchronization must include a regression at the boundary that could fail. Test observable outcomes rather than repeating an implementation formula.
| Layer | Location | Dependencies | Contract |
|---|---|---|---|
| Pure engine | src/engine.rs tests |
None | Owners and intervals, DST, fallback, pending/applied overrides, validation |
| Configuration graph | src/configuration.rs tests |
None | Dependency removal/redirect, last-step and fallback protection, pending swap cancellation, approved-history retention, exact route permutation |
| CSV import | src/holidays.rs tests |
None | Country/date keys, quoting, BOM, duplicates, conflicts, invalid rows |
| Provider compilation | src/providers/ tests |
None | Unsupported capabilities fail; normalization detects changed ownership |
| Instance access, pure | src/access.rs, src/identity.rs tests |
None | Configuration validation (unknown fields, key/name/group rules, sign-in method required), exact group matching and administrator-over-employee, claim paths, HMAC bootstrap passwords per hour/user/secret, contact-merge rules, username derivation |
| Application/persistence | tests/integration.rs, tests/support/ |
Disposable PostgreSQL | Real Cot migrations, scoped authorization, concurrent edits, atomic audit/history/outbox, approval revalidation |
| Instance access, database | tests/access.rs |
PostgreSQL with CREATEDB | Configuration sync (create, adopt, rename, disable, re-enable, safety refusals, ambiguity), group-derived roles and revocation, instance administrators acting without membership, employee permission set, bootstrap accounts across hours and concurrent replicas, administrator operations and workspace deletion, SSO account creation/revocation and email contact linking |
| SSO over HTTP | tests/oidc.rs, tests/support/fake_oidc.rs |
PostgreSQL with CREATEDB + loopback | The real application behind a fake OpenID provider: state cookie and one-time flow, PKCE, RS256 verification, rejected issuer/audience/expiry/nonce/signature, groups from ID token and userinfo, no-groups refusal without an account, session cookies, no registration endpoint |
| Demo lifecycle | tests/demo_lifecycle.rs |
PostgreSQL with CREATEDB | Database protection and reset, demo configuration seeding with the six accounts, retention and reseeding (own binary because the demonstration notice is process-wide) |
| HTTP provider contract | Integration suite + stateful local fake | PostgreSQL + loopback | Wire methods/payloads, partial 429 failure, checkpoint recovery, read-back, drift, external overrides, owned-only deletion |
| Browser/API | tests/browser*.cjs (all listed in npm run test:browser) |
Freshly started demo + Chromium | Forms, calendar, approval, workspace isolation, CSRF/origin, people/imports/timezones, removal dependencies, native routing drag/drop and position editing, desktop/mobile; browser-access.cjs: demo login guide, no registration, SSO error banner, instance page and read-only rules, employee permission editing, role-based views |
| Live acceptance | Dedicated JSM test team | Test credentials | Actual provider timeline, subscription-specific escalations and routing; never ordinary CI |
Invariants
- Every schedule covers the requested range without gaps or overlaps. Tests exercise a year across five zones and five shift lengths.
- Spring and autumn weekly shifts can be 167 or 169 hours while handing over at 11:00 local. Exact boundaries belong to the incoming employee. Invalid local handovers fail.
- Overrides change only their interval, not the base sequence. Pending requests have no effect. Overlapping approved state is an error.
- Coverage uses secondary, then the effective fallback including overrides. Country holidays skip only affected people; legacy global holidays select fallback directly. Cycles fail validation.
- Swaps apply both legs or neither. Requesters cannot approve for someone else. Application rechecks availability and ownership. Force requires a grant and is audited; comments are optional.
- One of two edits with the same revision wins. A failed constraint leaves document, revision, history, audit, and job unchanged.
- Schedule removal rewrites references, cancels affected pending requests in full, and commits one history/audit/outbox change. It cannot erase a current/future approved replacement or leave an empty escalation or broken fallback.
- Route ordering requires every current ID exactly once. Missing, repeated, foreign, stale, or unauthorized requests change nothing. Changing priority preserves conditions/recipients and survives reloads.
- Publication snapshots cannot read newer revisions. Past absence flags do not block a now-correct future plan.
- Competing workers cannot claim the same unexpired lease. Retrying a lost checkpoint does not create duplicate remote resources.
- External changes and overrides block writes/deletion by default; unmanaged resources survive reconciliation.
Running and extending
JSM regressions validate both plain and og- team UUIDs, reject malformed/path-like identifiers, and publish/recover against a paginated fake containing more than 50 unmanaged schedules. The fake rejects oversized Operations pages and preserves the prefixed team path.
Verify readable names for schedules, escalations and routing, rename without duplicate creation, and legacy-name recovery without a checkpoint. A changed legacy resource must still trigger drift protection.
Exact-time JSM coverage tests model half-hour rounding for rotations and millisecond precision for overrides. Verify arbitrary future boundaries, an ongoing shift exported without a past-start override, exact termination of its base coverage, recovery after an override create succeeds but its response fails, manual override conflicts, replacement/removal, expired coverage and owned parent deletion. Compare the live final timeline on an isolated temporary disabled schedule, then remove it.
Before an immediate worker tick, integration fixtures wait until their latest database-generated history timestamp is effective on the worker clock. This tolerates bounded container/host clock skew without treating a future revision as already active; skew of two seconds or more fails the fixture explicitly.
cargo test runs pure tests and explicitly reports database tests as ignored. With MEGURI_TEST_DATABASE_URL pointing at a disposable PostgreSQL 17 database whose user has CREATEDB, CI and developers run everything with cargo test --locked --tests -- --ignored --test-threads=1. Scheduling fixtures create uniquely keyed workspaces and users through the real sync and group path and never truncate shared tables; tests whose subject is whole-instance state (sync, bootstrap, administration, SSO) use IsolatedDatabase, a uniquely named database dropped at the end, because sync disables every unconfigured workspace. Run serially because worker tests inspect the global queue. Worker tests explicitly prioritize only their own job so a bounded batch cannot skip it because of jobs left by a prior run. tests/oidc.rs installs process-wide configuration and therefore holds one test function.
The fake models JSM responses and is not a substitute for live acceptance. New endpoints need verification against official documentation, a wire assertion, and a failure/recovery test. Do not make the fake accept an invented contract to get tests green.
CI database preflight connects from the same job container and with the same URL as integration tests. Service health alone does not verify that the job can reach PostgreSQL. Diagnose connection failures separately from application assertions; do not skip the integration suite when preflight fails.
All browser suites launch through tests/support/browser.cjs. MEGURI_BROWSER_CHANNEL=chromium selects Playwright's bundled browser without a branded channel; unset selects locally installed Chrome. Individual suites must not hardcode launch channels. CI installs Chromium and sets this variable for the whole browser run.
Binding-preview regression uses the nested demo project objects, checking project names, ordered responsible people and their scoped identities. It also verifies that invalid field types retain a readable preview while server validation reports the error.
Before enabling a provider in production: publish a preview to its dedicated test team, compare the actual timeline, repeat unchanged, interrupt a partial publication, introduce external drift, verify conflict and explicit overwrite, and exercise escalation/routing on the target subscription. Record evidence and limitations.
See JSM environment and acceptance preparation for current test-site options and the live verification sequence.
Additional regression cases
Cover independent handovers and dependent fallback boundaries, DST rejection, country-specific coverage, scoped directory selection, email contacts without access, import quoting/BOM/duplicates/errors/stale previews, atomic working-interval propagation, and exact JSM email resolution before writes. Browser coverage includes person selection by email, absence selection, reactive CSV preview/import, and readable escalation/routing flows on desktop and mobile.
Variables, absence planning, and demo lifecycle
src/absence.rs tests range splitting across independent handovers, automatic project promotion, uncovered diagnostics, preserved owners, and replacement validation. tests/generation.rs checks deterministic 30-project expansion, stable IDs on rename/reorder, typed dictionary errors, loop scope, fallback cycles, protected applied replacements, workspace-specific IDs, three-person priority, country holidays, and a Monday rotation crossing autumn DST.
The PostgreSQL suite checks read-only previews, grouped absence approvals, atomic workspace-variable activation, permission isolation, stale reviews, concurrent activation, country snapshots, and no contact-to-login grants. Demo tests use uniquely named disposable databases with CREATEDB: unmarked/normal protection, safe isolation, application-only reset with unrelated sentinel data preserved, repeated migration/seed, creation-based soft deletion, later physical purge, and reseeding. Never repoint these tests at a production DB.
The two additional browser suites (browser-absence.cjs, browser-generation.cjs) exercise actual forms and early server errors, persistent/reloaded state, the permanent demo banner and login guide, generated source editing, country accordions, DD-MM-YYYY, bulk replacements, and desktop/mobile layouts. Inspect screenshots rather than trusting DOM assertions alone.
Localization/navigation regressions check supported browser fallback, persistent account preference, parameter safety, complete catalogs, no literal template text, direct links, reload, workspace changes and browser history. Generation browser checks retain server errors, atomic activation and stable generated IDs while exercising inline controls and the source-owner link.
Exact-time cover regressions exercise same-day partial cover, workspace clock defaults despite a different display zone, server ownership checks, malformed clock values, DST folds/gaps and 23/25-hour calendar days. Generator browser tests assert that binding edits replace the main form and live validation remains inside the viewport even at the top of a long form.
Legacy compatibility regressions deserialize two-person schedules and dynamic generation bindings into priority-owner resources while preserving participant order, resource identity, fallback, handover and routing references.
tests/browser-binding-preview.cjs checks reactive formatted binding values beside server type errors, clearing missing selections, first-row lookup context and mobile sizing without saving draft changes.
browser-generation-scroll.cjs checks scroll restoration from an editor near the bottom of a long rule on desktop/mobile and verifies template styling is limited to non-interactive blocks.
audit unit tests preserve comments and unknown IDs while resolving references. PostgreSQL regression checks historical names after rename, raw UUID preservation and cross-workspace lookup isolation.
browser-setup-layout.cjs checks compact review state, country holiday counts, collapsed widgets, import access and mobile width. Demo holiday imports also run through integration seed/reset checks.
Repeated-cover regressions check approval gating, partial interval splitting, preserved original legs, stale-owner rejection, forced corrections and calendar interaction on an already replaced day.
The setup inventory browser checks cover collapsed resource rows, the schedule-type creation chooser, top utility widgets, desktop/mobile sizing, and absence of the old anchor/example controls. Configuration browser checks expand manual rows before deletion/reordering and retain drag-and-drop routing coverage.
Advanced demo regression checks dependent iteration filtering, inherited regional handovers/participants, tier-based escalation settings and working windows, shared tier edits with stable resource IDs, and early validation of a newly enabled entry with a missing tier. Integration seed/reset verifies all four workspaces.
browser-advanced-demos.cjs opens both advanced generation editors, verifies clean server previews, and checks the demo workspace access matrix for Alice, Bob and Carol.
Setup layout checks also verify iteration-source summaries, omission of zero iterations, collapsed resource descriptions and source-rule navigation for all three resource kinds.
Diagnostics regression covers bad participant data, primary/secondary errors, scoped source links, draft-preserving navigation, always-visible status and recovery to valid. Absence tests cover exact interval selection, independent schedule ranges, rejection of overlap/out-of-absence bounds, and unchanged bulk range behavior.
browser-diagnostics.cjs exercises invalid participant data, rule/variable links with local draft retention, and recovery to a valid status on mobile. browser-absence.cjs additionally selects an uncovered impact row and checks exact schedule/time bounds before the existing bulk workflow. PostgreSQL tests verify exact absence coverage remains pending until approval and leaves surrounding hours uncovered.
Unified absence editor tests change the start time of a shortcut-created range, verify resulting server boundaries, and use the same date/time controls for manual ranges. Unit coverage includes local range scope, half-open bounds and DST rejection.
Coverage diagnostics distinguish pending approval from missing substitutes. Pending request boundaries split uncovered intervals so partial requests never disguise remaining gaps. The UI shows substitutes and outstanding approvers, links to requests, and keeps publication blocked until approval. Browser regression covers partial pending coverage, remaining gaps, approver filtering, and responsive spacing.
Schedule setup places narrower variable and generation-rule panels beside a stacked availability sidebar. Absences and holidays remain open; their lists scroll internally. Country holiday groups retain accordions inside the bounded list, with add/import actions opening dialogs. Responsive layout moves the sidebar below the editors. Browser checks cover column position, bounded holiday expansion, visible actions and mobile width.
Generated routing placement is shown only when manual routes and an enabled route-generating rule coexist. Options name the manual routes in evaluation order; the stored insertion index is unchanged. Browser checks verify hidden controls for generated-only setups and named options/order for mixed routing.
Resource inventory is a distinct UI component (resource-inventory.html). All expanded resource kinds share resource-details.html: labeled icon rows, consistent spacing, sequential connectors, and a common source-rule control. Presentation rows and monochrome SVG paths come from pure UI helpers; schedules, routing order and provider state are unchanged. Check rotation, fixed owner, priority fallback, escalation timing/repeats and routing conditions on desktop/mobile.
Expanded resources use compact type-specific horizontal widgets instead of parameter tables: rotation metadata plus ordered people, priority people plus fallback, escalation steps plus repeat footer, routing conditions plus destination. Shared icon, chip and connector styles keep them consistent. Chains wrap within narrow screens; source links and edit actions retain their common placement.
The generation-rule editor is a generic technical constructor: visible iteration aliases and collection bindings, an explicit optional condition, and typed output blocks. New rules start without implicit project/responsible-variable detection or generated blocks. Variable names carry no semantic meaning. Compact controls retain the existing typed binding editor, value preview, live server diagnostics and draft semantics. Check no-iteration rules, nested collection bindings, conditions and multiple output types on desktop/mobile.
Binding selection uses one anchored, viewport-clamped popover beside the originating control; the constructor remains visible and keeps its scroll position. All source kinds, nested lookups/lists, paths, text affixes and live value previews remain supported. Literal escalation delays are directly editable. Done/Escape closes the popover and returns focus. Server and change previews are collapsed summaries with counts and bounded change lists. Browser checks cover context retention, source editing, nested bindings, keyboard dismissal and mobile bounds.
browser-repeat-defaults.cjs verifies absent escalation defaults render as editable numbers, edited values survive reopening the draft, and explicit dictionary lookups remain intact.
The main Acme Engineering demo contains six services (Payments, Search, Billing, Identity, Data platform, Developer portal), each with two or three ordered owners drawn from five login members: alice, bob, carol, dave, erin. All five share the weekly Monday 11:00 Time off rotation. Dave and Erin only access Acme; Carol also has Support/Commerce access through her groups. Other demo workspaces remain separate. The login password is the one generated for the run.
Generation rule results use the actual authorized server expansion, including schedules, escalation policies and routes, with resolved names and compact settings. The panel is always present with explicit checking, invalid, disabled and empty states; it respects iteration filters and does not simulate generation in the browser. Preview data contains only scheduling resources and scoped people, never integration configuration.
Permanent assignees are tested as single-participant rotations, including absence, replacement approval and publication blocking. The removed fixed-assignee schedule and generation types are rejected rather than normalized.
Workspace isolation regressions exercise independent memberships and variables, a single revision for configuration and working-time changes, read-only generation preview, stale review rejection, atomic activation/history/outbox, and workspace-administrator settings permissions.
The default Engineering example stores projects as one list of dictionaries: each entry has name and an ordered responsible person list. The Project iteration reads both fields directly from its current entry; no parallel responsible lookup variable is needed. The independent on_call list still defines the shared weekly rotation.
Variable editing uses a bounded, progressively disclosed tree: only the root starts expanded, object rows show names and collection summaries, and nested values expand in place. Values mode hides type/key controls; Structure mode exposes them without losing edits. Duplicate assigns fresh IDs recursively; ordering and live server validation remain intact. Check nested editing, duplication, mode switching and narrow viewports.
Generation map opens from Generation rules as a read-only, draggable/zoomable Cytoscape canvas. Server preview returns actual iteration counts, input contexts, predicate outcomes and produced IDs; no scheduling evaluation is duplicated in JavaScript. Iterated outputs start collapsed into a group; inspecting a node or pass reveals source data and verified resources. Invalid drafts show diagnostics rather than stale resources. The map is a captured draft preview refreshed explicitly, and never applies changes. Bundled Cytoscape 3.33.1 is served locally with its MIT license; no CDN or new framework is required. Browser coverage checks groups, details, source navigation, pan/zoom and mobile layout; engine regression verifies traced pass results.
The generation map arranges numbered rules in saved execution order from left to right, joined by solid sequence arrows. Variables occupy the upper band in first-consumer order, rules and their iterations and conditions occupy the middle band, and outputs occupy their producer columns in the lower resource band. Dashed edges show data dependencies. Repeated output groups expand into individual resources within the resource band. Browser checks verify rule ordering, band separation, output expansion and manual resources.
Map input details display evaluated server values for each block and pass, never serialized bindings. Shared values are deduplicated across passes; differing values are explicitly counted. Generated references collapse to type/name cards, and people resolve by display name. Empty binding metadata and raw reference UUIDs are not presented. Condition operands and escalation recipients/delays come from the same resolver used during expansion.
The map’s all-passes input overview lists deduplicated upstream sources, not expanded output settings: variables with used binding addresses and resource references grouped by producing block. References internal to the selected whole rule are omitted; selecting an individual output block shows its dependencies. Selecting a concrete pass still exposes its evaluated field values.
Expanded map resources use type-specific labeled fields and the same compact reference cards as inputs, never JSON dumps. Priority schedules show ordered people, fallback and zoned handover; rotations add anchor/cycle; policies show recipient/timing/condition and repeat behavior; routes show conditions, working window and destination. Reference names resolve from the preview snapshot. Browser regression checks visible names, participant order and absence of UUID metadata.
Access and identity regressions
Authorization boundaries are product failures like scheduling ones. A change to configuration sync, group mapping, roles, SSO, bootstrap or administration needs a regression in tests/access.rs, tests/oidc.rs or the pure tests. Existing cases pin: exact (not prefix/case-insensitive) group matching; membership removal when a group or workspace disappears, including for open sessions; instance administrators acting on workspaces without membership and being audited under their own ID; employees unable to administer integrations or members; the employee permission set applying to existing and future employees at once, with view mandatory and administrator-only permissions refused; refusal of a configuration that would disable everything and of ambiguous adoption before any write; bootstrap passwords equal for replicas in one UTC hour, rotated (ending sessions) in the next, and locked out when the block is removed; no SSO account takeover by a bootstrap name; SSO accounts created only when groups map, revoked at the next sign-in, never given a password; administrators unable to edit their own groups or SSO groups; deletion only of disabled, unconfigured workspaces with the typed key; contact linking rewriting the current document while history keeps the old ID and audit still resolves it, skipping ambiguous or conflicting data and never granting access.
The browser access suite also runs against the real demo. No test may weaken these checks to make a failing sign-in pass; fix the cause or record the limitation.
JSM deletion regressions remove checkpointed schedules (including coverage), escalations, routes and individual managed overrides, then republish with drift blocking enabled. Verify replacement IDs, refreshed dependent references, lost replacement-response recovery, no child reads against missing parents, and an unchanged subsequent publication without duplicate writes.
Explicit publication and shared drafts
Saving workspace configuration, approving replacements, importing data and editing generator drafts never authorize provider writes. These changes persist in PostgreSQL and are visible to other authorized members. Ordinary unfinished modal forms remain local until Save. Generator drafts autosave separately, including invalid intermediate values, with their own optimistic revision and workspace scope.
The top Review changes panel compares desired resources with the last successfully published document. Its Sync button is yellow when unpublished changes exist. Sync validates/applies the shared generator draft and explicitly authorizes a specific workspace revision; stale reviews fail. Provider status, errors and create/update/remove counts live in this panel. Failed authorized publications may retry the same snapshot; newer saved changes must never enter those retries. Successful jobs do not automatically refresh their horizon: the displayed coverage end requires a further explicit sync to extend it.
The worker persists the authorized document and publishes that snapshot, not the newest workspace document. A click while a publication lease is active is rejected. Existing jobs are paused by the manual-publication migration until an explicit click. Published snapshots survive history pruning. Tests cover no writes before a click, pinned retries across later edits, no periodic writes after success, scoped shared-draft persistence, stale concurrent edits, resource review against the published baseline, and the browser workflow across sessions.
browser-manual-sync.cjs uses isolated accounts and workspaces with the mock provider. It checks that saved manual resources and generated resources appear together in the publication review, remain unpublished across worker ticks, survive logout/login, and can be published by another authorized member. Desktop/mobile screenshots cover the yellow pending button and its cleared state after verification.
Compact recurring provider rotations
A plain base rotation whose effective published coverage matches its ordered calendar-day cycle is exported to JSM as one finite recurring rotation named after the schedule. The engine supplies the current cycle phase, ordered participants and calendar-day shift length; the provider only translates these fields to daily/weekly API values. The remote schedule ID and ownership marker stay unchanged. A publication replaces the old per-shift rotations rather than accumulating new ones. Native boundary precision must be representable; irregular effective coverage and replacements retain the exact interval export. The canonical expanded timeline remains available for verification and preview. Tests cover mid-shift starts, pre-anchor phases, participant ordering, DST, replacements, migration of an existing owned schedule and idempotent repeated publication.
When an owned JSM schedule has one current and one desired rotation, edits preserve the rotation ID through the dedicated rotation PATCH endpoint. Schedule metadata is patched without a rotations array. Verified intermediate writes are checkpointed; a durable pending-step snapshot recovers a lost response without mistaking that exact planned state for external drift. Tests model nested rotation replacement by schedule PATCH and require stable rotation identity across participant reorder, rename, retry and unchanged republish. Historical rows already retained by JSM are not deleted by this repair.
Workspace state save/reload controls live beside Sync in the top Review changes panel. The localized hint distinguishes shared draft autosave, validated local application, and explicit publication; Sync includes application, so a separate save is optional. Reload retrieves the shared draft, not a historical rollback. Removing a variable or generation rule requires confirmation before mutating or autosaving the draft. Browser regression covers cancellation, confirmation, top-panel controls and narrow layout.
JSM coverage rotation names use the schedule name, including priority coverage and the exact-time base rotation. Multiple finite rotations append the interval start in the schedule IANA timezone with date, time and UTC offset to distinguish DST folds. This is presentation only; ownership markers, coverage, checkpoints and explicit publication remain unchanged. Existing rotation names update on the next authorized synchronization.
Manual and generated routing editors expose the existing greater-than and less-than operations. Priority follows alert severity (P1 highest); P3 and above is represented as less-than P3 with negate=true, including the boundary. The editors show comparison controls without an additional priority instruction; the provider wire contract is unchanged.
Publication status exposes the lease expiry and a server-calculated publication_busy flag. Sync is disabled for an active lease, not merely the persisted publishing state. The review panel explains restart recovery and expired leases; normal polling refreshes eligibility. Restart never clears a live lease. PostgreSQL regression checks active-lease rejection and explicit reauthorization after expiry.
Nested binding paths retain the raw input text while typing, including trailing spaces and slash separators. The parsed path still updates live for shared drafts and server previews. Reopening shows the normalized path; changing source resets it. Browser regression types a nested list path character by character and checks its resolved value, edits, reopening and source reset.
JSM omits repeat when escalation repeats are disabled. Read-back and drift comparison accept an absent repeat field only for an expected escalation with waitInterval: 0 (the provider disabled representation). Present repeat objects and enabled repeats remain strictly compared. Fake-server regressions reproduce omission, recovery without a checkpoint, idempotence and detection of externally enabled repeats. No overwrite policy is needed to recover an otherwise matching escalation.
Sync immediately shows submitting feedback, then stays disabled for an authorized pending job as well as an active publication lease. Pending publication has a visible queue message. The UI polls every two seconds while queued or leased and keeps the twenty-second idle refresh; expired leases remain manually recoverable. A successful sync request updates local queue status before refreshing the workspace. Browser regression holds the queued response and verifies disabled state and automatic completion without reload.
Generated escalation steps support Everyone on the team in addition to schedules and people. The optional team_all flag defaults to false for existing drafts; team recipients do not resolve an individual binding. They compile to Recipient::TeamAll and JSM uses the configured workspace integration team ID with notifyType=all. Delay and acknowledgment condition remain explicit. Generator, wire-contract and browser regressions cover the 30-minute team step and legacy recipients.
Layered generation map and value provenance
The read-only map uses three separated horizontal bands: variables, generators, resources. Generator columns follow saved execution order; variables sort by first consumer, and generated resources occupy their producer column. Manual resources are included in the resource band with explicit manual attribution. Shapes distinguish bands; resource colors distinguish schedules, escalations and routes. Expanding output groups retains these bands.
Server preview provides binding provenance using the same resolver as generation: source bindings, iteration sources, lookup keys, list items, intermediate path values, final values, node identities and errors. The browser presents this captured snapshot rather than re-evaluating scheduling logic. An inspector popover supports history, source navigation and per-pass examples. Dotted address segments are independently colored, with neutral separators; quoted keys containing dots remain intact. Generated names retain separate bound and literal affix segments, and resource fields link to their binding or explicit default/manual origin. Clicking the map backdrop closes it; clicks on the canvas only clear selection. Tests cover provenance, layout, manual resources, source exploration and safe text rendering.
The value explorer renders source traversal as ordered monospace steps with neutral arrows and a selected-step indicator. Source navigation is a separate footer action; producer fields are independent choices rather than sequential path steps. Browser coverage checks stage values and separate source navigation.
Portable generation configuration
meguri/v2 defines compact JSON import/export (with legacy v1 import support) for variables and generators only. Merge by name retains omitted inputs; nested identity keys preserve resource identity across editing and repeated imports. People transfer by email, manual resource references by exact name, and generated links by generator/block. The server provides a read-only parsed/expanded preview and revalidates before saving the shared draft with workspace and draft revisions. Provider writes require a later explicit Sync. Tests cover cross-workspace remapping, repeated imports, unknown fields, scoped permissions, stale previews, email contacts, parse errors and browser application.
Compact portable configuration
meguri/v2 is the default export: ordinary JSON variables, typed wrappers only for special scalar types, compact binding references, flattened output fields, readable output keys and omitted semantic defaults. The v1 importer remains supported. Inactive binding metadata must never be exported. Human output keys persist in shared drafts; list entries reconcile by unique name/value first and position for unmatched edits. The preview remains authoritative for identity-changing edits. Regression checks compare expanded resources, repeat imports and actual size reductions.
The Import / Export dialog includes a localized Guide tab with a complete compact v2 reference, defaults, binding scope, operations, limits, merge semantics and a runnable example covering all output types. Copy guide copies every section as Markdown for hand editing or LLM use, without workspace data. Switching tabs preserves import text and does not apply it. Browser checks verify copying, sample preview, tab preservation and mobile layout.
Random team escalation regression coverage includes generator compilation with an unused invalid binding, conflicting recipient flags, portable v1/v2 round trips, fake-JSM notifyType: random, and browser selection/shared-draft reload.
Contact approval regressions cover account-to-contact immediate application, contact-to-account pending approval, contact-only absence planning by an editor, actor permissions, and unchanged account/membership counts. Existing regressions retain account-holder approval, swap and workspace isolation checks. tests/browser-contact-approval.cjs verifies immediate application without a force flag, readable preview, and calendar persistence.