diff --git a/hypaware-core/plugins-workspace/claude/skills/hypaware-privacy/SKILL.md b/hypaware-core/plugins-workspace/claude/skills/hypaware-privacy/SKILL.md index 6d560eaf..a4ddfb3b 100644 --- a/hypaware-core/plugins-workspace/claude/skills/hypaware-privacy/SKILL.md +++ b/hypaware-core/plugins-workspace/claude/skills/hypaware-privacy/SKILL.md @@ -91,9 +91,9 @@ WHERE cwd = '' ORDER BY date DESC LIMIT 40" --format json --output /tmp/sam Before you propose or apply **anything**, explain the classes in plain language, including what the org can and cannot see in each case: -- **ignore** (`hyp ignore --private `): never recorded going forward; the machine-local rule stops capture at the source. Existing cached rows are **purgeable** (Step 6) but are not removed by marking alone. The org sees **nothing** from this directory. -- **local-only** (`hyp ignore --local-only `): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history. -- **sync** (`hyp ignore --sync `): the explicit "this ships" choice - forwarded to the org server like the default. Marking `--sync` records an explicit decision so this directory is not asked about again. The org sees this directory's captured exchanges. +- **ignore** (`hyp policy set ignore`): never recorded going forward; the machine-local rule stops capture at the source. Existing cached rows are **purgeable** (Step 6) but are not removed by marking alone. The org sees **nothing** from this directory. +- **local-only** (`hyp policy set local-only`): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history. +- **sync** (`hyp policy set sync`): the explicit "this ships" choice - forwarded to the org server like the default. Marking it `sync` records an explicit decision so this directory is not asked about again. The org sees this directory's captured exchanges. Name the trade honestly: `local-only` keeps your history usable locally; `ignore` is stronger (nothing is even recorded once marked) but you lose local queryability too. @@ -112,14 +112,14 @@ Then **apply nothing without per-item user confirmation.** Propose, wait for a y Apply each confirmed decision **only** through the `hyp` verbs below. **Never** author policy files or write anything into the user's repositories - the machine-local store is the only target. ```bash -hyp ignore --private # class: ignore (stop recording this dir) -hyp ignore --local-only # class: local-only (record here, never forward) -hyp ignore --sync # class: sync (explicit "this ships") -hyp ignore --check # report the governing source + class, and residual cached rows; never writes -hyp unignore --private|--local-only|--sync # symmetric removal per class +hyp policy set ignore # class: ignore (stop recording this dir) +hyp policy set local-only # class: local-only (record here, never forward) +hyp policy set sync # class: sync (explicit "this ships") +hyp policy show # report the governing source + class, and residual cached rows; never writes +hyp policy unset [class] # remove markings (class-neutral by default; a trailing class scopes it) ``` -`hyp ignore --check ` names **which source governs** (a committed `.hypignore` dotfile vs a machine-local entry) and the entry's class, and reports how many already-cached rows still sit under it - the residue that purge (below) clears. Marking is always **non-destructive**: it changes future capture/forwarding, not existing cached rows. +`hyp policy show ` names **which source governs** (a committed `.hypignore` dotfile vs a machine-local entry) and the entry's class, and reports how many already-cached rows still sit under it - the residue that purge (below) clears. Marking is always **non-destructive**: it changes future capture/forwarding, not existing cached rows. **For every directory you mark `ignore`, and every session you flag as sensitive, offer `hyp purge` as a separately confirmed step** so that "completely ignored" also means "not sitting in the cache". Purge is destructive and cache-only (it never contacts the server); confirm each purge on its own. @@ -129,10 +129,10 @@ hyp purge --session # delete all cached rows for one session (cheapest: hyp purge --ignored # sweep every cached row whose cwd currently resolves to `ignore` ``` -Purge prompts for confirmation on a TTY; it errors on a bare `hyp purge` with no target. Sequencing matters: **mark `--private` first, then purge** - purging a directory that still resolves to `sync`/default warns that the next backfill will re-import it. Once a directory is `ignore`d, the capture seam blocks re-import, so the purge is durable. A common close-out for a directory the user wants fully gone: +Purge prompts for confirmation on a TTY; it errors on a bare `hyp purge` with no target. Sequencing matters: **mark the directory `ignore` first, then purge** - purging a directory that still resolves to `sync`/default warns that the next backfill will re-import it. Once a directory is `ignore`d, the capture seam blocks re-import, so the purge is durable. A common close-out for a directory the user wants fully gone: ```bash -hyp ignore --private && hyp purge +hyp policy set ignore && hyp purge ``` ## After the review diff --git a/hypaware-core/plugins-workspace/codex/skills/hypaware-privacy/SKILL.md b/hypaware-core/plugins-workspace/codex/skills/hypaware-privacy/SKILL.md index 99681060..21274a18 100644 --- a/hypaware-core/plugins-workspace/codex/skills/hypaware-privacy/SKILL.md +++ b/hypaware-core/plugins-workspace/codex/skills/hypaware-privacy/SKILL.md @@ -119,9 +119,9 @@ WHERE cwd = '' ORDER BY date DESC LIMIT 40" --format json --output /tmp/sam Before you propose or apply **anything**, explain the classes in plain language, including what the org can and cannot see in each case: -- **ignore** (`hyp ignore --private `): never recorded going forward; the machine-local rule stops capture at the source. Existing cached rows are **purgeable** (Step 6) but are not removed by marking alone. The org sees **nothing** from this directory. -- **local-only** (`hyp ignore --local-only `): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history. -- **sync** (`hyp ignore --sync `): the explicit "this ships" choice - forwarded to the org server like the default. Marking `--sync` records an explicit decision so this directory is not asked about again. The org sees this directory's captured exchanges. +- **ignore** (`hyp policy set ignore`): never recorded going forward; the machine-local rule stops capture at the source. Existing cached rows are **purgeable** (Step 6) but are not removed by marking alone. The org sees **nothing** from this directory. +- **local-only** (`hyp policy set local-only`): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history. +- **sync** (`hyp policy set sync`): the explicit "this ships" choice - forwarded to the org server like the default. Marking it `sync` records an explicit decision so this directory is not asked about again. The org sees this directory's captured exchanges. Name the trade honestly: `local-only` keeps your history usable locally; `ignore` is stronger (nothing is even recorded once marked) but you lose local queryability too. @@ -140,14 +140,14 @@ Then **apply nothing without per-item user confirmation.** Propose, wait for a y Apply each confirmed decision **only** through the `hyp` verbs below. **Never** author policy files or write anything into the user's repositories - the machine-local store is the only target. ```bash -hyp ignore --private # class: ignore (stop recording this dir) -hyp ignore --local-only # class: local-only (record here, never forward) -hyp ignore --sync # class: sync (explicit "this ships") -hyp ignore --check # report the governing source + class, and residual cached rows; never writes -hyp unignore --private|--local-only|--sync # symmetric removal per class +hyp policy set ignore # class: ignore (stop recording this dir) +hyp policy set local-only # class: local-only (record here, never forward) +hyp policy set sync # class: sync (explicit "this ships") +hyp policy show # report the governing source + class, and residual cached rows; never writes +hyp policy unset [class] # remove markings (class-neutral by default; a trailing class scopes it) ``` -`hyp ignore --check ` names **which source governs** (a committed `.hypignore` dotfile vs a machine-local entry) and the entry's class, and reports how many already-cached rows still sit under it - the residue that purge (below) clears. Marking is always **non-destructive**: it changes future capture/forwarding, not existing cached rows. +`hyp policy show ` names **which source governs** (a committed `.hypignore` dotfile vs a machine-local entry) and the entry's class, and reports how many already-cached rows still sit under it - the residue that purge (below) clears. Marking is always **non-destructive**: it changes future capture/forwarding, not existing cached rows. **For every directory you mark `ignore`, and every session you flag as sensitive, offer `hyp purge` as a separately confirmed step** so that "completely ignored" also means "not sitting in the cache". Purge is destructive and cache-only (it never contacts the server); confirm each purge on its own. @@ -157,10 +157,10 @@ hyp purge --session # delete all cached rows for one session (cheapest: hyp purge --ignored # sweep every cached row whose cwd currently resolves to `ignore` ``` -Purge prompts for confirmation on a TTY; it errors on a bare `hyp purge` with no target. Sequencing matters: **mark `--private` first, then purge** - purging a directory that still resolves to `sync`/default warns that the next backfill will re-import it. Once a directory is `ignore`d, the capture seam blocks re-import, so the purge is durable. A common close-out for a directory the user wants fully gone: +Purge prompts for confirmation on a TTY; it errors on a bare `hyp purge` with no target. Sequencing matters: **mark the directory `ignore` first, then purge** - purging a directory that still resolves to `sync`/default warns that the next backfill will re-import it. Once a directory is `ignore`d, the capture seam blocks re-import, so the purge is durable. A common close-out for a directory the user wants fully gone: ```bash -hyp ignore --private && hyp purge +hyp policy set ignore && hyp purge ``` ## After the review diff --git a/src/core/cli/remote_commands.js b/src/core/cli/remote_commands.js index 662ac53e..aedad071 100644 --- a/src/core/cli/remote_commands.js +++ b/src/core/cli/remote_commands.js @@ -535,7 +535,8 @@ async function runBrowserLogin(name, { org, host, noBrowser, noForward, noDaemon // privacy refinement is now the first-sync review window plus the // hypaware-privacy skill, run afterwards against a settled cache. Login // finishes fast; each fork prints the durable-command hint so the CLI floor - // (`hyp ignore --local-only`, `hyp ignore --private`) stays discoverable. + // (`hyp policy set [path] local-only`, `hyp policy set [path] ignore`) stays + // discoverable. // No sink targets this server yet: provision one so login forwards from one // command (LLP 0063 D2/D5). enrollCentralSink writes join's sink block, seeds diff --git a/src/core/commands/local_only.js b/src/core/commands/local_only.js index ed90bfc1..12a9cd4c 100644 --- a/src/core/commands/local_only.js +++ b/src/core/commands/local_only.js @@ -12,7 +12,7 @@ import { executeQuerySql } from '../query/sql.js' // after the in-login picker's retirement (LLP 0102): the review window plus // the hypaware-privacy skill are the enrollment-time refinement now, and this // command is the client-independent way to withhold a directory at any time. -export const DURABLE_HINT = "tip: mark a directory local-only anytime with 'hyp ignore --local-only [path]'\n" +export const DURABLE_HINT = "tip: mark a directory local-only anytime with 'hyp policy set [path] local-only'\n" // The dataset the captured-directory enumeration reads. Exported so the // hypaware-privacy skill's survey (LLP 0069 #enumerate, LLP 0100 §skill) and diff --git a/src/core/commands/purge.js b/src/core/commands/purge.js index 40caaa3e..e900eacf 100644 --- a/src/core/commands/purge.js +++ b/src/core/commands/purge.js @@ -125,7 +125,7 @@ export async function runPurge(argv, ctx) { `still record and will be re-imported by the next backfill:\n` ) for (const dir of resurrectable) ctx.stderr.write(` ${dir}\n`) - ctx.stderr.write("tip: mark them ignored first with 'hyp ignore --private ' so the purge is durable\n") + ctx.stderr.write("tip: mark them ignored first with 'hyp policy set ignore' so the purge is durable\n") } return 0 diff --git a/test/core/purge-command.test.js b/test/core/purge-command.test.js index afe2c904..2a02cd1e 100644 --- a/test/core/purge-command.test.js +++ b/test/core/purge-command.test.js @@ -334,7 +334,7 @@ test('runPurge subtree warns about resurrection when the dir still resolves full assert.equal(code, 0) assert.match(stderr.text, /still record and will be re-imported/) assert.match(stderr.text, /home\/u\/repoA/) - assert.match(stderr.text, /hyp ignore --private/) + assert.match(stderr.text, /hyp policy set ignore/) } finally { await fs.rm(cacheRoot, { recursive: true, force: true }) await fs.rm(hypHome, { recursive: true, force: true }) diff --git a/test/core/remote-login-command.test.js b/test/core/remote-login-command.test.js index d6f3aec0..47085df6 100644 --- a/test/core/remote-login-command.test.js +++ b/test/core/remote-login-command.test.js @@ -751,7 +751,7 @@ test('a --no-daemon login prints the durable hint and provisions the sink (LLP 0 const code = await runRemoteLogin(['prod', '--no-daemon'], ctx, { login }) assert.equal(code, 0) - assert.match(err.join(''), /hyp ignore --local-only/, 'the durable command stays discoverable') + assert.match(err.join(''), /hyp policy set \[path\] local-only/, 'the durable command stays discoverable') await fs.access(seedPath) // the sink is still provisioned assert.match(out.join(''), /forwarding logs to https:\/\/hyp\.internal/) }) @@ -766,7 +766,7 @@ test('a fresh enroll prints the durable hint and never polls a capture wait (LLP const code = await runRemoteLogin(['prod'], ctx, { login, enroll, waitForAttach }) assert.equal(code, 0) - assert.match(err.join(''), /hyp ignore --local-only/) + assert.match(err.join(''), /hyp policy set \[path\] local-only/) assert.match(out.join(''), /capturing @hypaware\/claude/) }) @@ -781,7 +781,7 @@ test('a failed daemon install still prints the durable hint before returning (LL const code = await runRemoteLogin(['prod'], ctx, { login, enroll, waitForAttach }) assert.equal(code, 3) assert.equal(waited, false, 'a failed install does not wait for attach') - assert.match(err.join(''), /hyp ignore --local-only/) + assert.match(err.join(''), /hyp policy set \[path\] local-only/) assert.match(err.join(''), /the daemon install did not finish/) }) @@ -795,7 +795,7 @@ test('a re-login (already-enrolled, re-seed path) prints the durable hint (LLP 0 const code = await runRemoteLogin(['prod'], ctx, { login }) assert.equal(code, 0) - assert.match(err.join(''), /hyp ignore --local-only/) + assert.match(err.join(''), /hyp policy set \[path\] local-only/) assert.match(out.join(''), /seeded forwarding identity for sink 'fwd'/) })