Add configured warm targets and convergence status

Open
#76 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
typescript

Research direction

Start with the WarmTargetConfig and WarmStatus contracts, the SimlockClient and SimlockAdminClient entry points, and dependencies #71, #72, #74, and #75. Trace convergence, activation confirmation, capacity accounting, and identity removal through the completion conditions; done means the listed idempotency, restart, capacity, status, and maintenance tests pass.

Written by the indexing model from the issue text.

Description

task:draft

Part of #70. See ADR 0021.

Purpose

Create ready devices before the first lease request.

The current warm pool keeps some released devices ready. It does not create devices to reach a configured target.

Simlock must remain the only owner of warm capacity and admission.

Configuration

interface WarmTargetConfig {
  target: number;
  maxCapacityFraction: number;
  shapePolicy: "demand-lru";
}

Use these defaults:

const defaults: WarmTargetConfig = {
  target: 0,
  maxCapacityFraction: 0.5,
  shapePolicy: "demand-lru",
};

target: 0 disables proactive work. A Host installation can set target: 1.

Client API

interface WarmActivation {
  deviceId: string;
  generation: number;
}

interface WarmStatus {
  target: number;
  ready: number;
  inProgress: number;
  state: "running" | "awaiting-external-fence" | "settled" | "blocked";
  activation?: WarmActivation;
  blocker?: SimlockError;
}

interface SimlockClient {
  getWarmStatus(): Promise<WarmStatus>;
}

interface SimlockAdminClient {
  convergeWarmTarget(input: { operationId: string }): Promise<WarmStatus>;
  confirmWarmActivation(input: {
    operationId: string;
    deviceId: string;
    generation: number;
  }): Promise<WarmStatus>;
}

The operation ID makes repeated calls safe after an uncertain response. Activation confirmation is idempotent for the same identity and generation. A stale generation or different identity fails without mutation.

Every reusable warm identity also uses the shared ManagedIdentityStatus lookup and removal acknowledgement from #72. This includes an identity that never receives a lease.

Capacity rules

  • Apply the limit to each platform managed limit.
  • Apply the limit to each platform running limit.
  • Apply the limit to the global running limit.
  • Keep one cold-demand slot free in each applicable limit.
  • Keep managed-device capacity charged until deletion completes.
  • Keep running capacity charged until shutdown or deletion completes.
  • Let cold demand remove the least recently used warm device.
  • Do not bypass the lease queue when capacity becomes free.

The effective target must satisfy the configured fraction and the cold-demand reservation in every applicable dimension. A capacity of 1 permits no warm device. A capacity of 3 with the default fraction permits at most 1.

Convergence rules

  • Start convergence after startup recovery completes.
  • Start convergence after grant, release, deletion, or catalog change.
  • Do not grant a device that fails health or cleanup.
  • For a reusable identity, return awaiting-external-fence before it can become ready.
  • Count the identity as ready only after Host installs or reattaches its pool-lifetime execution claim and confirms the exact generation.
  • Keep the identity reserved and capacity-bearing while confirmation is pending.
  • Persist removing and removed identity status when cold demand, health recovery, or maintenance removes a warm identity.
  • Keep removed status queryable across restart until Host acknowledges the exact generation.
  • Return settled only when Simlock reaches the effective target.
  • Return blocked with a typed reason when Simlock cannot reach the target.
  • While a maintenance epoch is active, reject non-epoch convergence and activation with MAINTENANCE_EPOCH_ACTIVE.
  • Let #77 use the same core activation transition with the active epoch. Do not create a second maintenance-only activation owner.

Completion conditions

  • Default installations do not create proactive warm devices.
  • Repeated convergence with one operation ID does not create duplicate devices.
  • Repeated activation confirmation returns the same result.
  • A stale activation confirmation cannot publish a reusable identity.
  • A non-epoch activation cannot advance an identity that waits inside maintenance.
  • Cold demand can use capacity after Simlock confirms warm-device removal.
  • Removal proof for a never-leased warm identity survives restart until Host acknowledges it.
  • Restart does not cause duplicate refill or a boot storm.
  • Status shows the target, current count, work in progress, pending activation, and terminal blocker.
  • Tests cover capacity values 1, 2, and 3 for all applicable limits.

Depends on #71, #72, #74, and #75.

Dominant language
TypeScript
Stars
14
Forks
0
Avg merge
22h 33m
Merged PRs (30d)
60

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from callstackincubator/simlock

All issues in callstackincubator/simlock

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.