Skip to content

hyp policy: class-neutral machine-local marking verb (LLP 0110/0111)#327

Merged
philcunliffe merged 16 commits into
masterfrom
integration/hyp-policy-verb
Jul 20, 2026
Merged

hyp policy: class-neutral machine-local marking verb (LLP 0110/0111)#327
philcunliffe merged 16 commits into
masterfrom
integration/hyp-policy-verb

Conversation

@philcunliffe

Copy link
Copy Markdown
Contributor

Mints hyp policy as the class-neutral machine-local marking verb, retiring the hyp ignore --sync misnomer (running "ignore" to opt a folder INTO syncing).

What changed

  • New verb group hyp policy set|show|unset|list (src/core/commands/policy.js, registered in core_commands.js), delegating to shared marking internals hoisted out of the flag branches. The LLP 0103 machine-local store, resolver, and class lattice are untouched.
  • hyp ignore / hyp unignore stay the honest dotfile verbs; the --sync / --local-only / --private / --check flags survive as output-compatible, help-text-deprecated aliases that delegate to the same internals (zero behavior change; existing alias tests pass unchanged).
  • Consent-sensitive copy migrated off the ignore spelling: the LLP 0106 SessionStart classification hook (verbArgvForClass now emits policy set <path> <token>, prompt text + pinned tests updated) and both hypaware-privacy SKILL.md bodies + hyp status/help wording.
  • Ref hygiene: verb surface cites LLP 0111, store rationale keeps citing LLP 0103#cli; ref-check green.

Provenance

Neutral pipeline: request LLP 0110 (issue, Accepted) -> design LLP 0111 -> plan LLP 0112 (6 tasks T1-T6), all tasks verified-merged. Implemented and reviewed by neutral, held for a human merge.

@ref LLP 0110 [implements]
@ref LLP 0111 [implements]

Change-Set: hyp-policy-verb

philcunliffe and others added 14 commits July 16, 2026 17:34
Generated-by: neutral

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Generated-by: neutral

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
…rnals

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
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>
…111)

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>
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
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
@philcunliffe

Copy link
Copy Markdown
Contributor Author

neutral review — round 1 (reviewed head 4e1c256, own change set, dual-review)

Verdict: clean / approve-grade. The change set does exactly what LLP 0110/0111 specify, and the PR own diff has no actionable finding.

Verified:

  • Alias zero-behavior-change (the hard requirement): hyp ignore --sync/--local-only/--private/--check delegate to the same hoisted runMarkMachineLocal/runUnmarkMachineLocal/runIgnoreCheck the policy runners call, with repoRootDefaultTarget, the cmd-ignore/cmd-unignore component, and the usage_policy.mark event preserved at the alias edge. The untouched ignore-private-sync-command.test.js compatibility suite passes unchanged.
  • Verb correctness: policy set <path> sync|local-only|ignore token map (sync -> full), exit-2 usage on bad tokens naming the three valid tokens, class-neutral unset, list enumeration, and policy show --json field-compatible with the old --check --json.
  • Consent-sensitive copy: the LLP 0106 hook emits [policy, set, path, token], both hypaware-privacy SKILL.md bodies migrated + consistent, pinned consent-copy tests assert the ignore-spellings are gone.
  • Style + refs: no semicolons/em-dashes, root-anchored type imports, all @ref LLP 0110/0111/0103/0049 anchors resolve, Extended-by: LLP 0110 present in 0103.

Out-of-scope residue (deferred, not a PR-diff finding): three sibling-skill lines still teach the deprecated-but-working hyp ignore --check (hypaware-sensitive-scan claude+codex, hypaware-reference codex). This does NOT violate the exit criterion (class-neutral reporter, not an ignore-spelled command for a non-ignore class) and is outside this PR declared T5 scope. Tracked as a follow-up: #328.

Non-attributable: a review pass flagged policy set <child> sync reporting "marked as full" when a stricter ancestor still governs, but those lines are unchanged by this PR (pure T1 hoist) - pre-existing behavior identical to the prior hyp ignore --sync alias, so not a regression here.

Reviewed-clean at the current head. Next tick: ready + held for you to merge.

…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>
@philcunliffe

Copy link
Copy Markdown
Contributor Author

Update: the deferred sibling-skill doc residue (previously tracked as #328) has been folded into this PR at commit 1e2b4f2 (hyp ignore --check -> hyp policy show in hypaware-sensitive-scan claude+codex and hypaware-reference codex; bare-dotfile hyp ignore mentions untouched). Doc-only, no behavior change. #328 is closed. The next review round covers this delta at the new head.

@philcunliffe

Copy link
Copy Markdown
Contributor Author

neutral review — round 2 (reviewed head 1e2b4f2, own change set)

Verdict: clean. The only delta since round 1 is the folded-in doc sweep: three sibling-skill lines now teach hyp policy show instead of the deprecated hyp ignore --check (hypaware-sensitive-scan claude+codex, hypaware-reference codex). Bare-dotfile hyp ignore/hyp unignore mentions untouched. No new findings. CI green (typecheck + test), MERGEABLE.

The misnomer migration is now complete across every user-facing surface. Reviewed-clean at the current head; next tick this is readied and held for you to merge.

@philcunliffe
philcunliffe marked this pull request as ready for review July 17, 2026 02:15
@philcunliffe philcunliffe added the neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030) label Jul 17, 2026
# Conflicts:
#	src/core/usage-policy/classification.js
#	test/core/usage-policy-classification.test.js
@philcunliffe philcunliffe removed the neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030) label Jul 20, 2026
@philcunliffe

Copy link
Copy Markdown
Contributor Author

neutral review - round 3 (reviewed head 43fa068, own change set, dual-review)

Verdict: clean. The head advanced from the round-2 head (1e2b4f2) only by a
merge from master (Merge remote-tracking branch 'origin/master' into HEAD),
whose second parent is c793698 (PR #329, LLP 0113: the classification ask is
a menu, not an open prompt). c793698 is already merged to master and was
already reviewed and shipped there. The PR's own diff against master is
unchanged since rounds 1 and 2.

Verified in a scratch worktree (git worktree add --detach 43fa068), not the
main checkout:

  • git log -1 --format='%P' 43fa068 confirms the two parents are 1e2b4f2
    (round-2 head) and c793698 (on master, verified via
    git merge-base --is-ancestor c793698 origin/master).
  • The merge brought in exactly c793698's four files: the LLP 0106 doc
    cross-link, the new LLP 0113 decision doc, classification.js, and its
    test - no files outside that set were touched.
  • The merge was not a trivial fast-forward union: replaying it with a plain
    git merge from 1e2b4f2 against c793698 does produce real textual
    conflicts in classification.js and its test, because both sides touch the
    same buildClassificationPrompt region (this branch's own hyp policy set
    rename versus master's new menu-mandate prose and a same-line @ref
    comment). The resolution actually committed in 43fa068 keeps both sides
    correctly: this branch's hyp policy set <cwd> <token> verb lines are
    intact, master's new "present as a selection menu / AskUserQuestion / unless
    no such tool exists" prose and its matching @ref LLP 0113 line are added
    alongside (not instead of) the existing @ref LLP 0111#teaching line, and
    the test file keeps both this branch's hyp policy set assertions and
    master's new menu-copy assertions. No conflict markers remain, and no edits
    landed beyond a correct union of the two sides.
  • npm test: 2283 tests, 7 failing, all in test/core/leave-command.test.js
    (unrelated hyp leave config-control assertions). The identical 7 failures
    reproduce on the round-2 head (1e2b4f2) and on master (c793698) in
    isolation, so they predate this merge and this PR entirely and are not a
    regression introduced here.

Change set is reviewed-clean at the current head. Next tick it is readied and
held for a human merge.

@philcunliffe philcunliffe added the neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030) label Jul 20, 2026
@philcunliffe
philcunliffe merged commit 66feddb into master Jul 20, 2026
4 checks passed
@philcunliffe
philcunliffe deleted the integration/hyp-policy-verb branch July 20, 2026 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

neutral:approved neutral reviewed this and holds it for a maintainer merge (own or adopted PR; LLP 0025/0030)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant