Atlas / Skills / nowork-studio / Notfair Upgrade Skill

Notfair Upgrade SkillSAFE

skills/nowork-studio/notfair-upgrade-skill

Open-source SEO, GEO, and marketing skills for AI agents.

Verdict
SAFE
Grade
B
Trust score
89 /100
Version
—
Hosts
1 documented
License
MIT
Stars
3,908
01

Overview

Open-source SEO, GEO, and marketing skills for AI agents.

Read from source at commit f08bca773eb5OBSERVED · 2026-10-08
02

Host compatibility

What the documentation claims. We have not run a compatibility test.

HostStatusNotes
claude-codementioned
03

What it tells the agent

The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.

---
name: upgrade
argument-hint: "<or just run '/notfair:upgrade'>"
description: >
  Upgrade the NotFair plugin to the latest version. Updates the marketplace repo,
  installs the new version to the plugin cache, and updates installed_plugins.json.
  Use when asked to "upgrade notfair", "update notfair", or "get latest version".
  Also handles inline upgrade prompts when a skill detects UPGRADE_AVAILABLE at startup.
allowed-tools:
  - Bash
  - Read
  - AskUserQuestion
---

# /notfair:upgrade

Upgrade the NotFair plugin to the latest version and show what's new.

## Key paths

| What | Path |
|------|------|
| Marketplace repo | `~/.claude/plugins/marketplaces/nowork-studio/` |
| Plugin cache | `~/.claude/plugins/cache/nowork-studio/notfair/<version>/` |
| Installed plugins | `~/.claude/plugins/installed_plugins.json` |
| Update state | `~/.toprank/` (intentionally preserved — see CHANGELOG 0.24.0) |

---

## Inline upgrade flow

This section is used when a skill preamble outputs `UPGRADE_AVAILABLE`.

### Step 1: Auto-upgrade

Log "Upgrading NotFair v{old} → v{new}..." and proceed to Step 2.

---

### Step 2: Detect current install

First check for dev symlink (see "Dev symlink detection" section). If detected, stop — do not upgrade.

```bash
# Find the currently installed plugin path
INSTALLED_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | grep -v '.bak' | head -1)
if [ -z "$INSTALLED_DIR" ]; then
  echo "ERROR: NotFair plugin not found in cache"; exit 1
fi
MARKETPLACE_DIR="$HOME/.claude/plugins/marketplaces/nowork-studio"
if [ ! -d "$MARKETPLACE_DIR/.git" ]; then
  echo "ERROR: marketplace repo not found at $MARKETPLACE_DIR"; exit 1
fi
echo "Current install: $INSTALLED_DIR"
echo "Marketplace repo: $MARKETPLACE_DIR"
```

### Step 3: Save old version

```bash
OLD_VERSION=$(cat "$INSTALLED_DIR/VERSION" 2>/dev/null | tr -d '[:space:]' || echo "unknown")
```

### Step 4: Update marketplace repo and install

```bash
cd "$MARKETPLACE_DIR"
git fetch origin
git reset --hard origin/main
NEW_VERSION=$(cat VERSION | tr -d '[:space:]')
GIT_SHA=$(git rev-parse HEAD)

# Create new versioned cache directory
NEW_CACHE_DIR="$HOME/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION"
if [ -d "$NEW_CACHE_DIR" ]; then
  rm -rf "$NEW_CACHE_DIR"
fi
mkdir -p "$NEW_CACHE_DIR"

# Copy plugin files (exclude .git to save space)
rsync -a --exclude='.git' "$MARKETPLACE_DIR/" "$NEW_CACHE_DIR/"
```

If the copy fails, warn: "Upgrade failed — the old version is still active. Run `/notfair:upgrade` manually." and stop.

### Step 5: Update installed_plugins.json

Read `~/.claude/plugins/installed_plugins.json`, then update the `notfair@nowork-studio` entry:

```bash
python3 -c "
import json, os
from datetime import datetime, timezone

path = os.path.expanduser('~/.claude/plugins/installed_plugins.json')
with open(path) as f:
    data = json.load(f)

data['plugins']['notfair@nowork-studio'] = [{
    'scope': 'user',
    'installPath': os.path.expanduser('~/.claude/plugins/cache/nowork-studio/notfair/$NEW_VERSION'),
    'version': '$NEW_VERSION',
    'installedAt': data['plugins'].get('notfair@nowork-studio', [{}])[0].get('installedAt', datetime.now(timezone.utc).isoformat()),
    'lastUpdated': datetime.now(timezone.utc).isoformat(),
    'gitCommitSha': '$GIT_SHA'
}]

with open(path, 'w') as f:
    json.dump(data, f, indent=4)
print('Updated installed_plugins.json: notfair@nowork-studio -> v$NEW_VERSION')
"
```

### Step 6: Clean up old cache versions

Remove old versioned cache directories (keep only the new one). Never remove a `dev` symlink:

```bash
for dir in ~/.claude/plugins/cache/nowork-studio/notfair/*/; do
  ver=$(basename "$dir")
  if [ "$ver" != "$NEW_VERSION" ] && [ "$ver" != "dev" ]; then
    rm -rf "$dir"
    echo "Removed old cache: $ver"
  fi
done
```

### Step 7: Write marker + clear update state

```bash
mkdir -p ~/.toprank
echo "$OLD_VERSION" > ~/.toprank/just-upgraded-from
rm -f ~/.toprank/last-update-check
rm -f ~/.toprank/update-snoozed
```

### Step 8: Show What's New

Read `$NEW_CACHE_DIR/CHANGELOG.md`. Find all version entries between the old version and the new version. Summarize as 3-7 bullets grouped by theme — focus on user-facing changes, skip internal refactors.

Format:
```
NotFair v{new} — upgraded from v{old}!

What's new:
- [bullet 1]
- [bullet 2]
- ...

The new version will be fully active on your next Claude Code session.
```

### Step 9: Continue

After showing What's New, continue with whatever skill the user originally invoked.

---

## Dev symlink detection

Before upgrading, check if the installed cache directory is a symlink named `dev`:

```bash
CACHE_DIR=$(ls -d ~/.claude/plugins/cache/nowork-studio/notfair/*/ 2>/dev/null | head -1)
if [ -L "${CACHE_DIR%/}" ] && [ "$(basename "$CACHE_DIR")" = "dev" ]; then
  echo "DEV_SYMLINK"
fi
```

If `DEV_SYMLINK`: tell the user "NotFair is installed as a dev symlink — it always points to your local source (v$(cat "$CACHE_DIR/VERSION" 2>/dev/null | tr -d '[:space:]')). No upgrade needed." and **stop**. Do not proceed with Steps 2–8.

---

## Standalone usage

When invoked directly as `/notfair:upgrade`:

1. Check for dev symlink (see "Dev symlink detection" above). If detected, stop.

2. Force a fresh update check (bypass cache and snooze):
```bash
_UPD_BIN=$(ls ~/.claude/plugins/cache/nowork-studio/notfair/*/bin/notfair-update-check 2>/dev/null | head -1)
[ -n "$_UPD_BIN" ] && _UPD=$("$_UPD_BIN" --force 2>/dev/null || true) || _UPD=""
echo "$_UPD"
```

3. If `UPGRADE_AVAILABLE <old> <new>`: follow Steps 2–8 above.

4. If no `UPGRADE_AVAILABLE` output: tell the user "You're already on the latest version (v{LOCAL})."
04

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeNA
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
none-observed
Network
none-observed
Shell
none-observed
Dependencies
pinned
Secrets in source
none-found

Findings (0)

No findings outside the package's declared scope.

Gates applied: no_behavioural_pass.

Audited 2026-10-08 · audit v0.4.1 · source sha f08bca773eb5full audit observations/trust-audit/skill/nowork-studio__notfair-upgrade-skill.json · Report an issue / request a re-scan
05

Audit history

Every audit this skill has had.

DateSourceVerdictGradeScoreChange
2026-10-08f08bca773eb5SAFEB89first audit
06

Questions

What does the Notfair Upgrade Skill skill do?

Open-source SEO, GEO, and marketing skills for AI agents.

Is Notfair Upgrade Skill safe to install?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.

What can Notfair Upgrade Skill access on my machine?

The audit observed no filesystem, network or shell use at all in its source.

Which assistants does Notfair Upgrade Skill work with?

Its documentation mentions claude-code. That is what the text claims, not a compatibility test we ran.

How current is this page?

The grade is for one exact copy of the source (f08bca773eb5), read on 2026-10-08. The repository is watched, and a new audit runs when it changes — this is the first audit.

Advertisement