# Share a managed token profile across agents

CLI/PHP **0.1.3** coordinates token lifecycle operations across processes that
use the same local app, grant, profile and keychain directory. Install the
[verified release](https://m7.org/docs/sdk/m7-identity/cli/installation.md) on every participating worker before sharing
that profile. Token/PHP remains storage-neutral and the CLI still requires
`token-php >=0.1.3 <0.2.0`.

## Upgrade existing workers

1. Stop workers that loaded an older CLI implementation.
2. Download the CLI/PHP 0.1.3 ZIP, SHA-256 checksum and manifest, verify the
   checksum, and extract into its own version directory.
3. Point every worker at the same updated CLI and the intended token library.
   Check `m7-identity --version` reports `0.1.3`.
4. Keep the existing protected keychain and select the app/profile explicitly.
   Restart workers with the updated code. An upgrade does not require a new
   device authorization or copying tokens between profiles.

Use the same keychain directory for processes sharing one grant. An independent
host or separately copied store needs its own authorized grant or an application
coordinator that spans those machines. Filesystem locking in one store cannot
coordinate another store.

## Renewal and safe contention

One process owns selection, renewal, complete pending checkpoint, ACK and active
promotion. Other processes cannot dispatch a competing lifecycle for that profile.
They return `Token lifecycle busy`; retry the managed operation after its current
owner completes. The retry reloads the winning package and normally reuses it.
This response does not mean that the grant expired or that the user must sign in.

```sh
./vendor/m7-identity-cli-php-0.1.3/bin/m7-identity ensure \
  --app example-device --profile agents \
  --refresh-mode ack_supersede_pending > /dev/null

./vendor/m7-identity-cli-php-0.1.3/bin/m7-identity token status \
  --app example-device --grant device-code --profile agents
```

The example assumes a configured and device-authorized native profile. Ensure
stores the complete resulting package before returning. Token status contains
metadata only; token, bundle and report output contain credentials and must not
be logged.

All supported managed writers participate: ensure and authenticated requests,
explicit refresh/ACK, machine acquisition, device pickup, import, promotion,
discard/reset and app/profile administration. Human approval waits stay unlocked;
each device token poll and its conditional storage commit run together. Other
profiles remain independent and protected-resource requests run after token
coordination releases.

Permanent private lock files live below the store's `.locks/` directory, outside
deletable profiles. The OS releases held locks when a process exits, including a
forced termination. Never unlink a lock file or steal it based on elapsed time.

## Delayed results and recovery

A sign-in/import, reset, recreation or configuration change invalidates older
acquisition attempts. A late pending response cannot replace a different active
generation. ACK promotion requires the exact package that was durably saved.
A failed operation cannot resave its old snapshot over a newer result.

A lost ACK response retains the exact pending activation for an idempotent retry.
Repeating that checkpoint does not create another generation. Locally obsolete
pending packages and equivalent legacy duplicates are retained in protected
history before automatic selection; distinct unresolved candidates require
inspection and explicit `--id` selection. Do not choose solely by a filename's
timestamp or delete all pending state to hide an uncertain result.

`ack_supersede_pending` is still the normal fault-tolerant authority mode, not a
replacement for client coordination. It can supersede a never-active child when
refreshing from the retained active predecessor. ACK confirms that specific child
before it is promoted locally.

If an interruption lasts until the acknowledged candidate's access token expires,
the authority can reject a repeat ACK even when its refresh credential remains
live. That case needs explicit recovery; the CLI never blindly promotes an
unconfirmed package or weakens revocation checks. Process-death recovery tests do
not establish durability against filesystem or power loss.

An authenticated resource request is not automatically replayed after a failure.
Only retry a business mutation when its dispatch status and the resource API's
idempotency contract establish that doing so is safe.

## Copies and custom storage

App/profile copy requires explicit source and destination and preserves permitted
configuration, passwords and access-only material without hard links. CLI/PHP
0.1.3 rejects a source containing refresh or activation bundles, including
history. Authorize a separate grant for an independently used profile; use one
shared profile for agents that should share a grant.

Explicit imports are deliberate operator replacements. Custom asynchronous CLI
store writers must capture the authorization epoch and condition their import on
that epoch. Raw file writes, separately copied stores and storage-neutral
`ensureAccessToken()` calls need caller-owned coordination, durable checkpointing
and conditional commits. The protocol library does not choose those policies.
