Skip to content

Commit 66feddb

Browse files
philcunliffeclaudeneutral-loop
authored
hyp policy: class-neutral machine-local marking verb (LLP 0110/0111) (#327)
* Design: hyp policy verb (covers LLP 0110) Generated-by: neutral Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Plan: hyp policy verb (LLP 0112, implements LLP 0111) Generated-by: neutral Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Hoist ignore/unignore marking internals into verb-agnostic shared impls Extract runMarkMachineLocal, runUnmarkMachineLocal, and runIgnoreCheck in src/core/commands/clients.js so they take an explicit resolved targetDir instead of computing it from parsed argv, and add repoRootDefaultTarget as the one shared repo-root-default placement rule. This is a pure refactor with zero behavior change: the flag branches in runIgnore/runUnignore now resolve the target and delegate, but stdout/stderr/exit codes are unchanged, so all existing ignore/unignore tests pass unmodified. This sets up both the flag forms and the future hyp policy runners (LLP 0112 T2) to call one implementation instead of drifting. Carries the existing @ref LLP 0103#cli annotations along with the moved code; gloss updates come in T6. Task-Id: T1 * Register hyp policy set/show/unset/list, delegating to shared T1 internals Adds the hyp policy command group (LLP 0110/0111) as the class-neutral successor to the ignore --sync/--local-only/--private aliases: thin runners in src/core/commands/policy.js parse CLI args and delegate to the shared runMarkMachineLocal/runUnmarkMachineLocal/runIgnoreCheck internals in clients.js, now exported and parameterized by a `component` attribute so telemetry still names the dispatching verb. runUnmarkMachineLocal gains a class-neutral mode (targetClass undefined) backing `policy unset <path>` with no trailing token, removing every machine-local entry governing a path regardless of class, alongside the existing class-scoped removal used by both `unignore` and `policy unset <path> <class>`. `policy list` enumerates the machine-local store directly with a --json {entries, path} shape; `policy show` reuses runIgnoreCheck so its --json output stays byte-compatible with `ignore --check --json`. New test/core/policy-command.test.js mirrors the existing ignore-private-sync-command coverage for the new spellings, plus list enumeration and class-neutral unset across multiple governing entries. Task-Id: T2 * Turn ignore/unignore marking flags into deprecated policy aliases The --sync/--local-only/--private/--check branches in runIgnore/runUnignore already delegate to the T1 hoisted internals (runMarkMachineLocal, runUnmarkMachineLocal, runIgnoreCheck) that the T2 policy runners call, so the delegation seam is single-implementation by construction and alias behavior cannot drift from the verb's. This task makes the compatibility posture explicit: - Annotate the delegation seam in both runners with // @ref LLP 0111#aliases [implements], noting the flag forms' repo-root defaulting is preserved at the alias edge (and unignore's cwd-relative no-default target likewise). - Mark the --local-only/--private/--sync/--check flags "deprecated: use hyp policy ..." in the hyp ignore / hyp unignore registry help, while stating the bare dotfile verbs are not deprecated. No runtime stderr warning (LLP 0111 #aliases). Zero behavior change: every existing alias test passes unchanged (stdout, stderr, exit codes, JSON fields, usage_policy.mark log event), the compatibility proof LLP 0110's exit criteria require. npm test (2284), typecheck, and build:types all green. @ref LLP 0111#aliases [implements] Task-Id: T3 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Migrate classification hook copy to hyp policy set (LLP 0106, 0110, 0111) Swap the consent-sensitive classification hook copy off the deprecated `hyp ignore --sync`/`--local-only`/`--private` misnomer and onto the class-neutral `hyp policy set <path> <token>` verb (registered since T2). - CLASSIFICATION_CHOICES: replace the `flag` field with the CLI-edge class `token` (`sync`/`local-only`/`ignore`). - verbArgvForClass now returns ['policy', 'set', targetPath, token], dispatched against the registry's two-word `policy set` path. - buildClassificationPrompt prints `hyp policy set <cwd> <token>`. - Pinned consent-copy tests updated in the same commit, plus an exit-criterion assertion that no ignore-spelled command is taught for a non-ignore class. - @ref glosses cite LLP 0111#teaching for the verb surface; the store and class rationale keeps citing LLP 0103#cli. Task-Id: T4 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * T5: migrate skill and status/help teaching copy to the hyp policy verb Both hypaware-privacy SKILL.md bodies (claude + codex) now teach the machine-local marking surface as `hyp policy set/show/unset` instead of the `hyp ignore --sync/--local-only/--private/--check` and `hyp unignore --<class>` misnomer. The bare `.hypignore` dotfile verbs are left untouched. Both bodies stay byte-consistent with each other. Swept the remaining runtime help strings that pointed users at the marking flags: the login durable-command hint (DURABLE_HINT) and the purge durability tip now name `hyp policy set ...`, with their pinned teaching-copy test assertions moved in the same commit. The alias behavior tests (hyp ignore --*/hyp unignore --*) are untouched and still pass as the compatibility proof. No product surface teaches an ignore-spelled command for a non-ignore class. Classification hook copy (classification.js) is out of scope here (T4); the JSDoc on the alias runners keeps naming the old flags because those functions are the aliases. @ref LLP 0111#teaching [implements] @ref LLP 0110 [implements] Task-Id: T5 * Ref hygiene sweep for hyp policy verb (LLP 0110/0111) Ran ref-check across the touched hyp-policy-verb surface (clients.js, policy.js, classification.js, core_commands.js, both hypaware-privacy SKILL.md bodies, and LLP 0103/0110/0111/0112) and found the verb-surface @ref citations already correct from T2-T5. The remaining stale spots were three doc comments left over from T1's carry-forward (repoRootDefaultTarget, runMarkMachineLocal, runIgnoreCheck) that still described the policy set/show runners as "a future task" and described repoRootDefaultTarget as shared with the future policy verb, when in fact policy set/show now exist and policy set deliberately never calls repoRootDefaultTarget (it marks the resolved path exactly as pointed at, per LLP 0111 #set). Corrected those glosses to state the current, already-landed relationship instead of a stale forward-looking one. Verified LLP 0103's Extended-by: LLP 0110 forward-ref still reads correctly against the final shipped verb surface. ref-check's only remaining findings in touched files are two pre-existing false positives against LLP 0086's HTML-anchor sections (the tool only scans markdown headings), unrelated to this change set and present before T1-T5 touched this file. No behavior change. npm test (2284 tests) and npm run typecheck both pass. Task-Id: T6 * Complete hyp policy doc sweep: hyp ignore --check -> hyp policy show in sibling skills Folds in the deferred minor review finding from PR #327 review round 1 (the sensitive-scan and reference skills still taught the deprecated hyp ignore --check alias). Doc-only; no behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: neutral-loop <neutral-loop@localhost>
1 parent 8185f65 commit 66feddb

18 files changed

Lines changed: 1248 additions & 133 deletions

File tree

hypaware-core/plugins-workspace/claude/skills/hypaware-privacy/SKILL.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ WHERE cwd = '<dir>' ORDER BY date DESC LIMIT 40" --format json --output /tmp/sam
9191

9292
Before you propose or apply **anything**, explain the classes in plain language, including what the org can and cannot see in each case:
9393

94-
- **ignore** (`hyp ignore --private <dir>`): 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.
95-
- **local-only** (`hyp ignore --local-only <dir>`): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history.
96-
- **sync** (`hyp ignore --sync <dir>`): 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.
94+
- **ignore** (`hyp policy set <dir> 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.
95+
- **local-only** (`hyp policy set <dir> 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.
96+
- **sync** (`hyp policy set <dir> 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.
9797

9898
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.
9999

@@ -112,14 +112,14 @@ Then **apply nothing without per-item user confirmation.** Propose, wait for a y
112112
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.
113113

114114
```bash
115-
hyp ignore --private <dir> # class: ignore (stop recording this dir)
116-
hyp ignore --local-only <dir> # class: local-only (record here, never forward)
117-
hyp ignore --sync <dir> # class: sync (explicit "this ships")
118-
hyp ignore --check <dir> # report the governing source + class, and residual cached rows; never writes
119-
hyp unignore --private|--local-only|--sync <dir> # symmetric removal per class
115+
hyp policy set <dir> ignore # class: ignore (stop recording this dir)
116+
hyp policy set <dir> local-only # class: local-only (record here, never forward)
117+
hyp policy set <dir> sync # class: sync (explicit "this ships")
118+
hyp policy show <dir> # report the governing source + class, and residual cached rows; never writes
119+
hyp policy unset <dir> [class] # remove markings (class-neutral by default; a trailing class scopes it)
120120
```
121121

122-
`hyp ignore --check <dir>` 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.
122+
`hyp policy show <dir>` 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.
123123

124124
**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.
125125

@@ -129,10 +129,10 @@ hyp purge --session <id> # delete all cached rows for one session (cheapest:
129129
hyp purge --ignored # sweep every cached row whose cwd currently resolves to `ignore`
130130
```
131131

132-
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:
132+
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:
133133

134134
```bash
135-
hyp ignore --private <dir> && hyp purge <dir>
135+
hyp policy set <dir> ignore && hyp purge <dir>
136136
```
137137

138138
## After the review

hypaware-core/plugins-workspace/claude/skills/hypaware-sensitive-scan/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ All examples redacted. Two groups, then the caveat:
9292
current session forward, reverse with `/hypaware-unignore`).
9393
- **Caveat (always).** The sensitive rows above are **already recorded**; ignoring is
9494
prospective and does not delete them. Show the residual with
95-
`hyp ignore --check <path>` (reports the governor and how many cached rows from the
95+
`hyp policy show <path>` (reports the governor and how many cached rows from the
9696
scope remain). Retroactive purge is out of scope.
9797

9898
## Notes

hypaware-core/plugins-workspace/codex/skills/hypaware-privacy/SKILL.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,9 @@ WHERE cwd = '<dir>' ORDER BY date DESC LIMIT 40" --format json --output /tmp/sam
119119

120120
Before you propose or apply **anything**, explain the classes in plain language, including what the org can and cannot see in each case:
121121

122-
- **ignore** (`hyp ignore --private <dir>`): 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.
123-
- **local-only** (`hyp ignore --local-only <dir>`): recorded and queryable **here** on this machine, but **never forwarded**. Withheld at the export seam. The org sees **nothing**, while you keep local history.
124-
- **sync** (`hyp ignore --sync <dir>`): 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.
122+
- **ignore** (`hyp policy set <dir> 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.
123+
- **local-only** (`hyp policy set <dir> 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.
124+
- **sync** (`hyp policy set <dir> 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.
125125

126126
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.
127127

@@ -140,14 +140,14 @@ Then **apply nothing without per-item user confirmation.** Propose, wait for a y
140140
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.
141141

142142
```bash
143-
hyp ignore --private <dir> # class: ignore (stop recording this dir)
144-
hyp ignore --local-only <dir> # class: local-only (record here, never forward)
145-
hyp ignore --sync <dir> # class: sync (explicit "this ships")
146-
hyp ignore --check <dir> # report the governing source + class, and residual cached rows; never writes
147-
hyp unignore --private|--local-only|--sync <dir> # symmetric removal per class
143+
hyp policy set <dir> ignore # class: ignore (stop recording this dir)
144+
hyp policy set <dir> local-only # class: local-only (record here, never forward)
145+
hyp policy set <dir> sync # class: sync (explicit "this ships")
146+
hyp policy show <dir> # report the governing source + class, and residual cached rows; never writes
147+
hyp policy unset <dir> [class] # remove markings (class-neutral by default; a trailing class scopes it)
148148
```
149149

150-
`hyp ignore --check <dir>` 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.
150+
`hyp policy show <dir>` 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.
151151

152152
**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.
153153

@@ -157,10 +157,10 @@ hyp purge --session <id> # delete all cached rows for one session (cheapest:
157157
hyp purge --ignored # sweep every cached row whose cwd currently resolves to `ignore`
158158
```
159159

160-
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:
160+
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:
161161

162162
```bash
163-
hyp ignore --private <dir> && hyp purge <dir>
163+
hyp policy set <dir> ignore && hyp purge <dir>
164164
```
165165

166166
## After the review

hypaware-core/plugins-workspace/codex/skills/hypaware-reference/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ registry.
146146
**hypaware-ai-spend-report**, **-adoption-report**, **-security-report**, or
147147
**-improvement-report** skills.
148148
- Opt a folder out of recording - `hyp ignore` / `hyp unignore` write or remove
149-
a `.hypignore` for the folder subtree (`hyp ignore --check` reports what
149+
a `.hypignore` for the folder subtree (`hyp policy show` reports what
150150
governs a path).
151151
- "Is it working?" or diagnose a problem - `hyp status` (with `--json` for the
152152
stable shape); its `diagnostics:` section carries `repair:` lines to run.

hypaware-core/plugins-workspace/codex/skills/hypaware-sensitive-scan/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ All examples redacted. Two groups, then the caveat:
9494
`hyp unignore` once the sensitive work is done).
9595
- **Caveat (always).** The sensitive rows above are **already recorded**; ignoring is
9696
prospective and does not delete them. Show the residual with
97-
`hyp ignore --check <path>` (reports the governor and how many cached rows from the
97+
`hyp policy show <path>` (reports the governor and how many cached rows from the
9898
scope remain). Retroactive purge is out of scope.
9999

100100
## Notes

0 commit comments

Comments
 (0)