Skip to content

Skill Invariants

Project Skills

Transition Rules

The following transition table governs synchronization planning for project skills.

Rule ID Status Selection & Mode Target & Evidence Classification & Default Action Post-State or Handling Fixture ID
INV-TR-01 [current] Selected, link / copy Target missing; canonical valid; state missing or present MISSING → CREATE Creates link or copy. For copy mode, writes active record $B := C$ (origin write). Link mode creates symlink without state record. FIX-TR-01
INV-TR-02 [current] Selected, any Canonical missing or unreadable BLOCK → CONFLICT Preflight halts execution without modifying target or state. Verified in tests/test_skill_plan.py::test_canonical_missing_or_unreadable. FIX-TR-02
INV-TR-03 [current] Selected, link Symlink accurately points to canonical resource OWNED → NOOP Link already points to canonical resource; no filesystem mutation. Verified in tests/test_skill_plan.py::test_link_mode_noop_when_owned. FIX-TR-03
INV-TR-04 [current] Selected, link Broken symlink pointing to canonical (source missing) OWNED + source missing → BLOCK Refuses to treat broken link as an empty slot. FIX-TR-04
INV-TR-05 [current] Selected, link Points to external/wrong resource; state missing FOREIGN / UNKNOWN → CONFLICT Refuses automatic relink. Sync aborted. FIX-TR-05
INV-TR-06 [current] Selected, link Previously managed, but link redirected elsewhere DRIFT / UNKNOWN → CONFLICT Stale record cannot override current directory entry fact. Verified in tests/test_skill_plan.py. FIX-TR-06
INV-TR-07 [current] Selected, copy Valid active state, $R = B = C$ OWNED_UNCHANGED → NOOP No file or state writes. Verified in tests/test_skill_plan.py::test_copy_mode_owned_unchanged_noop. FIX-TR-07
INV-TR-08 [current] Selected, copy Valid active state, $R = B$, $C$ changed OWNED_UNCHANGED → UPDATE Copies new $C$; updates baseline $B := C$ (origin write). Verified in tests/test_skill_plan.py::test_copy_mode_upstream_updated. FIX-TR-08
INV-TR-09 [current] Selected, copy Valid active state, $R \ne B$ and $R \ne C$ OWNED_DRIFTED → CONFLICT Blocks sync. Explicit --force replaces target; updates $B := C$ (origin write). Verified in tests/test_skill_plan.py::test_copy_mode_local_drift_conflict_and_force. FIX-TR-09
INV-TR-10 [current] Selected, copy Valid active state, $R \ne B$ but $R = C$ RECONCILE_STATE → NOOP on files Verifies existing ownership; atomically updates $B := C$ (origin reconcile). Verified in tests/test_skill_plan.py::test_copy_mode_reconcile_state. FIX-TR-10
INV-TR-11 [current] Selected, copy No state record, $R = C$ UNKNOWN → NOOP + Diagnostic Does not manufacture ownership. --force authorizes CLAIM_STATE ($B := C$, origin claim). Verified in tests/test_skill_plan.py::test_copy_mode_unmanaged_matching_requires_force. FIX-TR-11
INV-TR-12 [current] Selected, copy No state record, $R \ne C$, safe normal directory UNKNOWN → CONFLICT (Default); --force Overwrites Default blocks sync; --force creates active state $B := C$ (origin write). Verified in tests/test_skill_plan.py::test_copy_mode_unmanaged_conflicting_requires_force. FIX-TR-12
INV-TR-13 [current] Selected, copy State corrupt/mismatched, unreadable, or unsafe entry UNKNOWN → CONFLICT Checks directory readability, entry type, and state corruption; --force cannot bypass corruption. Verified in tests/test_skill_plan.py::test_copy_mode_corrupted_state_causes_conflict. FIX-TR-13
INV-TR-14 [current] Deselected, actual link Symlink points to workspace canonical resource OWNED → UNLINK Unlinks symlink entry only. FIX-TR-14
INV-TR-15 [current] Deselected, actual link External symlink or insufficient evidence FOREIGN / UNKNOWN → Preserve + Info Leaves link untouched; informs user. FIX-TR-15
INV-TR-16 [current] Deselected, actual copy Valid active state, any $R$ / $B$ / $C$ relation DEACTIVATE_STATE → Preserve target Sets state to inactive; target directory preserved untouched. Verified in tests/test_skill_plan.py::test_deselected_copy_skill_deactivates_state_and_preserves_dir. FIX-TR-16
INV-TR-17 [current] Deselected, actual copy Inactive state or no state record Preserve target → NOOP Never deletes copy. Does not alter state. FIX-TR-17
INV-TR-18 [current] Re-selected, copy Inactive state, $R = C$ UNKNOWN → NOOP + Diagnostic --force authorizes REACTIVATE_STATE ($B := C$, origin reactivate). Verified in tests/test_skill_plan.py::test_reselected_inactive_copy_matches_canonical. FIX-TR-18
INV-TR-19 [current] Re-selected, copy Inactive state, $R \ne C$ UNKNOWN → CONFLICT --force authorizes replacement and active baseline $B := C$ (origin write). Verified in tests/test_skill_plan.py::test_reselected_inactive_copy_differs_requires_force. FIX-TR-19
INV-TR-20 [current] Selected, mode switch Representation differs from desired mode Mode switch plan Link to copy: managed link replaced by copy ($B := C$, active). Copy to link: active copy with $R = B$ replaced by symlink (state inactive). Drifted, unmanaged, or inactive copy to link is blocked (CONFLICT); --force does not bypass. Verified in tests/test_skill_plan.py::test_mode_switch_link_to_copy, tests/test_skill_plan.py::test_mode_switch_copy_to_link. FIX-TR-20

Detailed Lifecycle Rules

Project Skills State Transitions

The table above governs synchronization planning for project skills.

Global Skills

Rules

INV-GLB-01: Global Skill Link-Only Contract [current]

Global skills operate exclusively in link mode. There is no copy mode, no baseline fingerprint record ($B$), no content state store, and no directory copy lifecycle. Ownership and state transitions are determined entirely from live filesystem directory entries and symlink destination verification.

INV-GLB-02: Exact Canonical Symlink for Managed Entries [current]

A managed skill entry (~/.agents/skills/<name>) is owned if and only if it is a symbolic link whose literal target resolves to <active_workspace>/skills/<name>. Symlinks pointing to other skills in the workspace, other workspaces, or external locations evaluate to FOREIGN / UNKNOWN and cause CONFLICT. Normal directories (even if content exactly matches canonical) and regular files evaluate to CONFLICT.

INV-GLB-03: Stale Entry Cleanup Invariant [current]

A deselected entry in ~/.agents/skills/ is unlinked if and only if it is a symbolic link pointing specifically to <active_workspace>/skills/<same-name> (or a broken symlink whose raw link target points to that canonical path). Unmanaged symlinks, external links, cross-skill links, and ordinary directories are strictly preserved and reported as conflicts. Content-matching copy cleanup (allow_matching_copies=True) is eliminated for global skills.

INV-GLB-04: Managed Container Preservation and Migration [current]

~/.agents/skills is a managed container hosting individual managed entries; it is never deleted when skills become empty. If ~/.agents/skills is a legacy symlink pointing specifically to the root of <active_workspace>/skills, it is safely migrated to a real directory (MIGRATE_CONTAINER) prior to entry writes. Symlinks pointing to subdirectories, other workspaces, or external targets evaluate to CONFLICT.

INV-GLB-05: Consumer Link Non-Relink Invariant (Breaking Change) [current]

Agent consumer skill targets (e.g. ~/.claude/skills) must resolve to the managed container ~/.agents/skills. If a consumer target exists as a symlink pointing to an unexpected destination or external path, Aikito halts with CONFLICT and preserves the target; automatic unlinking and relinking ([RELINK]) is eliminated.

INV-GLB-06: Same-Object Disposition (SHARED_PATH) [current]

When an Agent consumer target path resolves to the same physical object as the managed container (Target.is_same_object), the target is assigned the read-only disposition SHARED_PATH. It does not enter the Executor write operations set and creates no filesystem mutation.

INV-GLB-07: Shared Consumer Target Deduplication [current]

Multiple Agent consumers pointing to identical physical targets (e.g. 6 bundled agents sharing ~/.agents/skills) are deduplicated into a single physical Target. The target is inspected, planned, and applied exactly once per synchronization run.

INV-GLB-08: Idempotent Convergence [current]

In a stable configuration where all managed entries and consumer links point to their canonical targets, subsequent synchronization runs evaluate completely to NOOP or SHARED_PATH. Zero filesystem mutations occur, preserving file metadata, symlink destination, mtime_ns, and inode numbers without unlink/recreate cycles.

INV-GLB-09: Dry-Run Zero Mutation Guarantee [current]

aikito sync global --dry-run guarantees zero filesystem writes across $HOME, workspace, state storage, and temporary directories. No writer.lock is created.

INV-GLB-10: Bundled Refresh and Runtime Apply Serialization [current]

Bundled skill refresh and global skill runtime link application share the outermost WorkspaceWriterLock(home). Refresh outcomes must match plan expectations before runtime application proceeds; preflight failure halts execution without silent replanning.

INV-GLB-11: Global Result Segmentation [current]

Global synchronization results are strictly segmented. Failure during subsequent global instructions linking cannot corrupt, downgrade, or rewrite the recorded success of applied global skills.

State Transitions

Selected Managed Entry

Current State Planned Action Rule ID / Evidence Handling
Canonical missing or unreadable CONFLICT INV-GLB-02 Preflight halts execution; target untouched
Target missing CREATE INV-GLB-02 Creates symlink pointing to canonical <workspace>/skills/<name>
Target symlink exact to canonical NOOP INV-GLB-08 No filesystem mutation, preserves mtime_ns and inode
Target symlink points to other skill in workspace CONFLICT INV-GLB-02 Preserved untouched; reports unmanaged conflict
Target symlink points to other workspace CONFLICT INV-BIND-02 Preserved untouched; no automatic takeover
Target symlink points to external path CONFLICT INV-GLB-02 Preserved untouched; reports unmanaged conflict
Target is normal directory (identical or differing content) CONFLICT INV-GLB-01 Matching content rejected as ownership evidence; preserved
Target is regular file or unsupported entry CONFLICT INV-GLB-02 Refuses to overwrite; reports conflict

Deselected Stale Managed Entry (~/.agents/skills/<name>)

Current State Planned Action Rule ID / Evidence Handling
Symlink exact to <workspace>/skills/<same-name> UNLINK INV-GLB-03 Proves workspace ownership; unlinks link entry only
Broken symlink, raw target exact to canonical UNLINK INV-GLB-03 Proves prior ownership; unlinks stale broken link entry
Symlink points to another skill PRESERVE INV-GLB-03 Preserves cross-skill link untouched
Symlink points to other workspace / external PRESERVE INV-BIND-02 Preserves foreign link untouched
Normal directory (identical or differing content) PRESERVE INV-GLB-03 Content matching eliminated; directory preserved
Regular file or unsupported entry PRESERVE INV-GLB-03 Preserves unmanaged entry untouched
Current State Availability Planned Action Rule ID Handling
same_object Any SHARED_PATH INV-GLB-06 Read-only disposition; excluded from Executor write operations
Parent missing All consumers not_installed SKIP INV-GLB-05 Skips linking; does not create parent directory
Parent missing Any consumer installed CREATE_PARENT + CREATE_LINK INV-GLB-05 Creates parent directory and creates symlink to ~/.agents/skills
Parent missing unknown SKIP + Diagnostic INV-GLB-05 Refuses to guess installation; diagnostic finding emitted
Target missing, parent exists installed / unknown CREATE_LINK INV-GLB-05 Creates symlink pointing to ~/.agents/skills
Target correct symlink to ~/.agents/skills Any NOOP INV-GLB-08 No filesystem mutation, preserves mtime_ns and inode
Target wrong / external symlink Any CONFLICT INV-GLB-05 Breaking change: halts with conflict; automatic relinking eliminated
Target regular file / directory Any CONFLICT INV-GLB-05 Preserves existing entry; reports conflict

Legacy Top-Level Container Migration (~/.agents/skills)

Current State Planned Action Rule ID Handling
Exact symlink to <workspace>/skills root MIGRATE_CONTAINER INV-GLB-04 Safely unlinks legacy link and creates real directory before entry writes
Symlink to subfolder of skills/ CONFLICT INV-GLB-04 Ambiguous / invalid container target; sync aborted
Symlink to other workspace CONFLICT INV-BIND-02 Foreign workspace container; preserved; sync aborted
Symlink to external path CONFLICT INV-GLB-04 External path container; preserved; sync aborted