An Agent Skill that teaches an agent to build an on-premise fallback server: a Node box at a physical site holding a live two-way replica of that site's slice of Firestore, which takes over serving LAN terminals when the internet drops and flushes offline work back on reconnect. The local server is Node/NestJS + RxDB; the cloud is Firestore with Next.js route handlers as the reference API, both stated as substitutable.
While the internet is up the box is invisible: it replicates in the background and heartbeats so the cloud knows it is alive. When the cloud stops answering, kiosk and staff PWAs on the LAN switch their API base URL to it and the site keeps taking bookings, moving stock and toggling hardware from the replica.
The insight that shapes the whole skill: sync is two systems, not one. Document-level RxDB replication keeps state current but cannot run the cloud's business logic; an HTTP flush of business events on reconnect runs that logic, such as atomic stock increments and audit ingestion, but keeps nothing current. Neither path alone is sufficient, and both are keyed on client-generated IDs so their overlap converges instead of double-counting.
The skill was written by the engineers who have shipped this module; the earlier implementation it was
audited against was the on-premise fallback of a multi-location venue booking system. The templates hold four
properties: a live replica that takes over the LAN when the internet drops, a reconnect flush the cloud can
apply any number of times with one result, hardware calls that are HMAC-verified with a replay window, and
offline staff tokens that expire. The vitest suite in assets/ verifies the trust-critical logic, and
references/provenance.md is the record of what the audit changed, what was kept
and what is new.
One command, via the skills.sh CLI, which installs the skill into every skills-compatible agent it detects, including Claude Code, Codex CLI and Gemini CLI:
npx skills add timerise-ai/island-mode-serverName the agents instead with -a, for example npx skills add timerise-ai/island-mode-server -a claude-code -a codex.
Or clone it yourself. Nothing here is Claude-specific: the skill is a plain Agent
Skills folder, SKILL.md plus markdown references with no file that calls a model,
so cloning it into an agent's skills directory is all an install is. For Claude Code:
git clone https://github.com/timerise-ai/island-mode-server.git ~/.claude/skills/island-mode-serverTo scope it to a single project instead, clone it into that project's .claude/skills/ directory. For another
agent, clone into that agent's skills directory, or symlink the Claude Code copy so one git pull updates
every agent:
mkdir -p ~/.agents/skills
ln -s ~/.claude/skills/island-mode-server ~/.agents/skills/island-mode-serverUpdate the skill with git pull in its directory. The current release is 0.1.4. See
CHANGELOG.md. The skills index lists the other
Timerise Skills and how to install them all at once.
The skill activates automatically when a task matches its description: a physical site that must keep
operating through an internet outage, a PWA terminal that must switch between a cloud and a local API, a
reconnect flush that double-counts stock; also on the vocabulary: "island mode", "offline fallback server",
"LAN failover", "on-prem replica", replicateFirestore, serverTimestamp checkpoints, _offlineCreated,
heartbeat crons, HMAC device auth, "the site keeps working when the internet is down". Invoke it explicitly
with /island-mode-server in Claude Code, $island-mode-server in Codex CLI, or from /skills in Gemini
CLI.
Each host matches a task against the description its own way, so invoke the skill explicitly on a first run
rather than assuming it fired. Only SKILL.md is read up front; the references/ files load on demand, so
the skill stays cheap in context until a topic is actually needed.
| File | Contents |
|---|---|
SKILL.md |
Entry point: the architecture diagram, six critical facts, four hard rules, the quick start, and the reference directory |
references/architecture.md |
Modes, the two sync paths, replication tiers, tenant scope, the seams table |
references/replication.md |
RxDB setup, schemas, custom-token auth, security rules, the checkpoint trap |
references/sync-flush.md |
Reconnect flush, per-ID stock deltas, idempotent cloud ingestion, retries |
references/network-failover.md |
Heartbeat/status chain, outage detection, terminal API switching, rescan |
references/auth.md |
Local API guards: staff tokens, kiosk key, hardware HMAC, offline gating |
references/local-api.md |
The offline endpoints: availability, booking mutex, check-in, pricing |
references/operations.md |
On-site deployment: systemd, nginx TLS, mDNS, env vars, runbook |
references/provenance.md |
The ledger: what the audit changed, what was kept, what is new and not yet run |
assets/behavior.test.ts |
The vitest suite carried into the target project as regression cover |
The skill is server-side and infrastructure-side only; the local server has no UI at all, and its operator
surface is /health, /status and journald. It assumes Firestore is the cloud source of truth and stays that
way, and that the topology is hub-and-spoke with last-write-wins conflicts. The seams table in
references/architecture.md is the full boundary with the host; nothing else crosses it.
These travel with the module and are never optional. They are the hard rules in SKILL.md, and entries 1 to
4 of references/provenance.md record how the templates hold them:
- Never expose the cloud sync-ingestion endpoints without auth. They apply stock increments and inject orders, so they are reachable only with a shared-secret header at the minimum; the reference route handlers check it before touching Firestore.
- Never verify offline staff tokens leniently while online. Decoding without verification is an accepted LAN-only trade-off, so it is gated on the server actually being offline; the suite's offline token tests cover the gate.
- Never reset local stock deltas for transactions not acknowledged as synced. Deltas are folded out
per transaction ID on acknowledgment, so
effectiveStockstays correct across a partial flush; the suite's delta fold-out tests run against a real RxDB instance. - Never let the local server invent business rules the cloud owns (opening hours, pricing). The local server replicates the config and computes from it, so island-mode behaviour matches the website.
Everything else is the host app's: vocabulary, IdP, HTTP framework, UI, i18n.
The host supplies the other half of each seam:
| Seam | The skill ships | The host supplies |
|---|---|---|
| Domain entities | location/booking/inventory/lock/staff/pricing + a rename table |
Its vocabulary |
| Tenant scope | locationId, env-derived, one per server |
Its field name; array variant for directories |
| Cloud API | Next.js route handlers as reference | Any framework, via plain JSON-over-POST contracts |
| Staff identity | Firebase Auth ID tokens + role hierarchy | Its IdP; keep the online-verify/offline-lookup split |
| Hardware auth | HMAC-SHA256 shared secret | Its device fleet's capabilities |
| Local runtime | NestJS (DI + guards) | Any Node HTTP framework; services are plain classes |
| UI status surface | State shape only (mode, apiBaseUrl) |
Its own banner/indicator components |
| Strings | English literals, keys suggested | Its i18n system |
| Not this | Use instead |
|---|---|
| Cached reads, or a PWA that only needs offline persistence | The Firebase SDK's built-in offline mode, no server needed |
| Supabase, Postgres or another cloud database | The tier concept travels; every template here is Firestore-specific |
| Multi-master sync between peer sites | This design is strictly hub-and-spoke, cloud as source of truth |
| The kiosk terminal itself | The sibling booking-kiosk skill, which defines the client-side failover contract against this server |
Every TypeScript template compiles under strict and --noUncheckedIndexedAccess, Node-side against rxdb
16.11 / firebase 12 / firebase-admin 13 / @nestjs 11, Next-side against Next 16 / React 19. The trust-critical
logic passes assets/behavior.test.ts (12 tests: HMAC accept/tamper/replay,
offline-token expiry, delta fold-out on a real RxDB memory instance including partial and duplicate acks,
failover threshold and offline rescan). Carry that file into the target project as regression cover. It cannot
run in this repository: it imports templates that exist only once they have been copied into a host project.
Not verified by execution, and marked as such: the Firestore rules, the replication plugin against a live Firestore, and the nginx/systemd/avahi configs, which were reviewed against the earlier deployment only.
Issues and pull requests are welcome here. Pure markdown and TypeScript templates, with no build, lint or dev server in this repository. Claims in this skill are meant to be verifiable: if you change a factual claim, say how you verified it, whether against the library, the docs, or a reproduction.
Adding, removing or renaming a file in references/ means updating the quick start and the reference
directory table in SKILL.md, the file table above, and any relative cross-links. Every odd-looking part of
the templates is there for a reason, and references/provenance.md is the ledger that records which one:
read it before simplifying anything, and add an entry for anything you change. Commits follow Conventional
Commits and releases follow STANDARD.md in the
index; CLAUDE.md carries the full editing conventions.
This is one of the Timerise Skills: modules written by our own senior
engineers from the modules they have shipped, not synthetic, each published as its own repository and indexed
there. They share one layout, so an agent that has read one knows how to read the next: a SKILL.md entry
point, references/ loaded on demand, and a seam contract carrying the module's non-negotiables. Most of them
target Next.js App Router apps; this one is the on-premise counterpart, a Node service and its deployment,
for when those apps must survive losing the internet.
Built and maintained by Timerise.
MIT. See LICENSE.