@holdyourvoice/hyv 3.4.4 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/Readme.md +7 -0
  2. package/dist/agents/load.test.js +1 -1
  3. package/dist/ai-editor-rules.js +34 -0
  4. package/dist/ai-editor.js +120 -9
  5. package/dist/ai-editor.test.js +99 -8
  6. package/dist/ai-shadow-fixtures.js +7 -0
  7. package/dist/ai-shadow-generator.js +17 -0
  8. package/dist/backtest.js +16 -0
  9. package/dist/backtest.test.js +20 -0
  10. package/dist/cli.js +225 -8
  11. package/dist/cli.test.js +102 -5
  12. package/dist/editorial-packs.js +1 -0
  13. package/dist/hold-your-voice.mcpb +0 -0
  14. package/dist/local-eval.js +98 -0
  15. package/dist/local-eval.test.js +20 -0
  16. package/dist/mcp-tools.js +22 -2
  17. package/dist/mcp-tools.test.js +33 -1
  18. package/dist/mcp.js +35 -4
  19. package/dist/mcp.test.js +2 -2
  20. package/dist/pipeline.js +5 -4
  21. package/dist/pipeline.test.js +12 -0
  22. package/dist/profile-compose.js +97 -0
  23. package/dist/profile-compose.test.js +32 -0
  24. package/dist/profile-score.js +79 -0
  25. package/dist/profile-score.test.js +22 -0
  26. package/dist/profile-watch.js +34 -0
  27. package/dist/profile-watch.test.js +23 -0
  28. package/dist/profile.js +33 -2
  29. package/dist/profile.test.js +27 -0
  30. package/dist/rebuild-task.test.js +1 -1
  31. package/dist/rule-allowances.js +27 -0
  32. package/dist/rule-allowances.test.js +17 -0
  33. package/dist/sample-ingest.js +94 -0
  34. package/dist/sample-ingest.test.js +52 -0
  35. package/dist/strict-quality.js +64 -0
  36. package/dist/strict-quality.test.js +62 -0
  37. package/dist/version.js +1 -1
  38. package/dist/voice-dna.js +33 -1
  39. package/dist/voice-dna.test.js +12 -1
  40. package/dist/writing-examples.js +83 -0
  41. package/dist/writing-examples.test.js +35 -0
  42. package/package.json +56 -11
  43. package/skills/hyv-analyze/SKILL.md +3 -1
  44. package/skills/hyv-analyze/agent.json +2 -1
  45. package/skills/hyv-backtest/SKILL.md +14 -0
  46. package/skills/hyv-backtest/agent.json +16 -0
  47. package/skills/hyv-backtest/agents/openai.yaml +4 -0
  48. package/skills/hyv-evaluate-local/SKILL.md +14 -0
  49. package/skills/hyv-evaluate-local/agent.json +16 -0
  50. package/skills/hyv-evaluate-local/agents/openai.yaml +4 -0
  51. package/skills/hyv-final-check/SKILL.md +2 -0
  52. package/skills/hyv-find-writing-examples/SKILL.md +10 -0
  53. package/skills/hyv-find-writing-examples/agent.json +16 -0
  54. package/skills/hyv-find-writing-examples/agents/openai.yaml +4 -0
  55. package/skills/hyv-ingest/SKILL.md +31 -0
  56. package/skills/hyv-ingest/agent.json +28 -0
  57. package/skills/hyv-ingest/agents/openai.yaml +4 -0
  58. package/skills/hyv-patterns/SKILL.md +2 -0
  59. package/skills/hyv-profile/SKILL.md +2 -0
  60. package/skills/hyv-score/SKILL.md +26 -0
  61. package/skills/hyv-score/agent.json +28 -0
  62. package/skills/hyv-score/agents/openai.yaml +4 -0
  63. package/skills/hyv-strict-check/SKILL.md +26 -0
  64. package/skills/hyv-strict-check/agent.json +33 -0
  65. package/skills/hyv-strict-check/agents/openai.yaml +4 -0
  66. package/skills/hyv-verify/SKILL.md +1 -1
  67. package/skills/hyv-verify/agent.json +1 -0
@@ -0,0 +1,16 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-backtest",
4
+ "title": "hyv-backtest",
5
+ "description": "Evaluate a caller-supplied reconstruction against a held-out local target without generating text.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Information-isolated evaluator",
8
+ "workflow_phase": "verify",
9
+ "input": { "required": ["context path", "held-out target path", "candidate path", "profile path", "three or more held-out sample paths"], "optional": [] },
10
+ "output": { "required": ["text-free backtest report"], "optional": [] },
11
+ "evidence_requirements": ["Report preservation, AI Editor, and held-out-band results separately; never call the report an authorship or generation result."],
12
+ "permissions": ["execute_commands", "read_repository"],
13
+ "stop_conditions": ["Stop when the candidate was not supplied by the caller or fewer than three held-out samples are supplied."],
14
+ "tool_free_mode": { "available": true, "behavior": "Provide the exact command and state that the local backtest is NOT_RUN; never invent a score.", "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"] },
15
+ "handoff_to": ["hyv-verify"]
16
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Backtest"
3
+ short_description: "Evaluate a supplied reconstruction without generating text."
4
+ default_prompt: "Use $hyv-backtest to score a caller-supplied reconstruction against held-out local writing without making an authorship claim."
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: hyv-evaluate-local
3
+ description: Run the optional deterministic local writing evaluation composite without model calls.
4
+ ---
5
+
6
+ # hyv-evaluate-local
7
+
8
+ Evaluate a caller-supplied candidate against an input and separate local user and AI-shadow paragraph fixtures. The module trains only on the paragraph IDs assigned to the train split. It does not generate prose, transmit samples, retain text, or establish authorship.
9
+
10
+ ```text
11
+ hyv evaluate-local input.md candidate.md user-paragraphs.json ai-shadow-paragraphs.json
12
+ ```
13
+
14
+ Each JSON file is an array of `{ "paragraph_id": "stable-id", "text": "..." }`. Keep variants under the same paragraph ID; HYV splits by ID before training. The report contains a train-only TF-IDF logistic-regression proxy, content F1, AI-tell change, and 9-d stylometric cosine. Treat every number as a local evaluation signal, not a publishing decision or identity claim.
@@ -0,0 +1,16 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-evaluate-local",
4
+ "title": "hyv-evaluate-local",
5
+ "description": "Run the optional deterministic local writing evaluation composite without model calls.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Local writing evaluation reporter",
8
+ "workflow_phase": "verify",
9
+ "input": { "required": ["input path", "candidate path", "user paragraph JSON", "AI-shadow paragraph JSON"], "optional": [] },
10
+ "output": { "required": ["paragraph-isolated evaluation report"], "optional": [] },
11
+ "evidence_requirements": ["Report that the authorship component is a local train-only proxy, not an authorship verdict.", "Do not allow paragraph IDs in both train and test sets."],
12
+ "permissions": ["execute_commands", "read_repository"],
13
+ "stop_conditions": ["Stop when either fixture has fewer than two unique paragraph IDs or the JSON schema is invalid."],
14
+ "tool_free_mode": { "available": true, "behavior": "Provide the exact command and state that the report is NOT_RUN; never invent scores.", "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"] },
15
+ "handoff_to": ["hyv-verify"]
16
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Local Evaluation"
3
+ short_description: "Run an isolated local writing-evaluation composite."
4
+ default_prompt: "Use $hyv-evaluate-local to run the paragraph-isolated local evaluation composite without making an authorship claim."
@@ -7,6 +7,8 @@ description: Gate exact user-facing text from any model, tool, or interface.
7
7
 
8
8
  Gate exact final text from every producer. Returns output only when clean or after removing a leading byte-order mark; unresolved hidden characters withhold output. It does not require or select a VoiceDNA profile. Run it immediately before display, copy, export, posting, or returning an API response.
9
9
 
10
+ This is a hidden-text boundary only. It does not prove AI-pattern quality or voice matching. When the caller needs that stricter decision, run hyv-strict-check first, then run final-check again on the exact text that will be delivered.
11
+
10
12
  ## Usage
11
13
 
12
14
  ```text
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: hyv-find-writing-examples
3
+ description: Find redacted excerpts from explicit local writing samples in memory only.
4
+ ---
5
+
6
+ # hyv-find-writing-examples
7
+
8
+ Use the `hyv_find_writing_examples` MCP tool with a query and one to 64 explicit local `{ basename, text }` samples. It returns at most three ranked excerpts, redacts sensitive values, exposes basenames only, and never writes a corpus or index.
9
+
10
+ Pass approved examples to `hyv_rewrite_prompt` only as advisory cadence evidence. They cannot override preservation, facts, AI Editor blockers, or final-output checks.
@@ -0,0 +1,16 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-find-writing-examples",
4
+ "title": "hyv-find-writing-examples",
5
+ "description": "Find redacted excerpts from explicit local writing samples in memory only.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Private style evidence finder",
8
+ "workflow_phase": "analyze",
9
+ "input": { "required": ["query", "one to 64 explicit local samples with basenames"], "optional": [] },
10
+ "output": { "required": ["up to three redacted excerpts with basenames"], "optional": [] },
11
+ "evidence_requirements": ["Report only basenames and redacted excerpts. Never claim an index was stored or a network request was made."],
12
+ "permissions": ["execute_commands", "read_repository"],
13
+ "stop_conditions": ["Stop when samples are not explicitly supplied, a source is not a basename, or the query has no useful local terms."],
14
+ "tool_free_mode": { "available": true, "behavior": "State that local example lookup is NOT_RUN and provide the exact MCP operation; never invent excerpts.", "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"] },
15
+ "handoff_to": ["hyv-rewrite-prompt"]
16
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Writing Examples"
3
+ short_description: "Find redacted local style examples without storing an index."
4
+ default_prompt: "Use $hyv-find-writing-examples to find up to three redacted excerpts from explicit local writing samples."
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: hyv-ingest
3
+ description: Redact an owner-authorized Gmail or Telegram export into local VoiceDNA samples.
4
+ ---
5
+
6
+ # hyv-ingest
7
+
8
+ Turn an explicitly authorized local Gmail Sent.mbox or Telegram Desktop JSON export into redacted writing samples. This is opt-in local preprocessing, not background collection, training, synchronization, or network access.
9
+
10
+ ## Usage
11
+
12
+ ```text
13
+ hyv ingest <gmail-sent-mbox|telegram-desktop-json> export --owner=owner --output=/absolute/safe-directory [--blocked=word]
14
+ ```
15
+
16
+ ## Preconditions
17
+
18
+ - Confirm the source is authorized by its owner and select the source type exactly.
19
+ - Use an existing absolute output directory outside every Git checkout. The command creates new `samples.jsonl` and text-free `receipt.json`; it refuses existing files and never overwrites exports.
20
+ - Add `--blocked=word` for each user-supplied term that must drop its entire sentence. Do not put secrets or sample prose in command output or a status message.
21
+
22
+ ## Behavior
23
+
24
+ - Only messages attributable to the explicit owner are retained.
25
+ - Email addresses, phone numbers, card-like values, IP addresses, and URLs are deterministically redacted before `samples.jsonl` is created. The receipt records counts and digests, never raw prose, paths, or source content.
26
+ - Presidio is optional. If no approved adapter ran, report `NOT_CONFIGURED`; do not imply it was installed.
27
+ - This command makes no provider call, telemetry event, network request, profile, or model. It cannot open a socket.
28
+
29
+ ## Handoff
30
+
31
+ Inspect the new samples locally, then use `hyv-profile` to build a profile or `hyv-score` with a separately held-out set. Do not add the redacted export to a repository without separate approval.
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-ingest",
4
+ "title": "hyv-ingest",
5
+ "description": "Redact an owner-authorized Gmail or Telegram export into local VoiceDNA samples.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Private sample hygiene operator",
8
+ "workflow_phase": "analyze",
9
+ "input": {
10
+ "required": ["gmail-sent-mbox or telegram-desktop-json source", "explicit owner identifier", "absolute existing output directory outside every Git checkout"],
11
+ "optional": ["--blocked=word sentence-drop entries"]
12
+ },
13
+ "output": { "required": ["new redacted samples.jsonl", "new text-free receipt.json"], "optional": [] },
14
+ "evidence_requirements": [
15
+ "Confirm the explicit source type, owner identifier, output directory, and receipt counts without reproducing sample prose.",
16
+ "State Presidio as NOT_CONFIGURED unless an approved adapter actually reports otherwise."
17
+ ],
18
+ "permissions": ["execute_commands", "read_repository", "write_repository"],
19
+ "stop_conditions": [
20
+ "Stop when ownership is not explicit, the output is relative, inside a Git checkout, missing, or already contains either output file, or the source type is not supported."
21
+ ],
22
+ "tool_free_mode": {
23
+ "available": true,
24
+ "behavior": "Provide the exact local command and state that ingest is NOT_RUN; never claim redaction or write output without execution.",
25
+ "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"]
26
+ },
27
+ "handoff_to": ["hyv-profile", "hyv-score"]
28
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Ingest"
3
+ short_description: "Redact an owner-authorized Gmail or Telegram export into local writing samples."
4
+ default_prompt: "Use $hyv-ingest to create redacted local samples from an owner-authorized Gmail or Telegram export without network access."
@@ -16,6 +16,8 @@ hyv patterns
16
16
  ## Behavior
17
17
 
18
18
  - Deterministic and local-first: this command never calls a provider and never sends drafts, samples, profiles, or telemetry to a service.
19
+ - The catalog is evaluated against author prose only; rule listing does not imply that a pattern proves AI authorship.
20
+ - Profile v3 may disable only an eligible default through signed non-verbatim sample evidence. Inspect the profile policy separately because explicit policy wins.
19
21
  - Commands that write use an explicit output path. Confirm that path before running the command.
20
22
  - This agent describes how to invoke the command and what it returns. It does not change command behavior or exit codes.
21
23
 
@@ -16,6 +16,8 @@ hyv profile profile.json sample-a.md sample-b.md [sample-c.md] [--avoid=phrase]
16
16
  ## Behavior
17
17
 
18
18
  - Deterministic and local-first: this command never calls a provider and never sends drafts, samples, profiles, or telemetry to a service.
19
+ - This command writes the stable Profile v2 shape. For channel-specific V3 profiles use `hyv profile v3 profile.json --id=writer.email --channel=email sample-a.md sample-b.md [--tone=0,0,0,0,0] [--avoid=phrase]`; it signs policy and sample allowances without retaining raw prose. To blend approved V3 profiles locally, use `hyv profile compose --ratio 70:30 profile-a.json profile-b.json`.
20
+ - To rebuild a V3 profile after explicit sample changes, use `hyv profile watch /absolute/profile.json --id=writer.email --channel=email sample-a.md sample-b.md`. The watcher debounces named local files and writes only to an existing, non-Git absolute directory; stop it with Ctrl-C.
19
21
  - Commands that write use an explicit output path. Confirm that path before running the command.
20
22
  - This agent describes how to invoke the command and what it returns. It does not change command behavior or exit codes.
21
23
 
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: hyv-score
3
+ description: Score a draft against an explicit held-out local writing band.
4
+ ---
5
+
6
+ # hyv-score
7
+
8
+ Use this with three or more samples that were not used to build the profile. It reports whether a candidate sits inside the writer's observed range. It is local-only and is not an authorship, factuality, or publication-quality score. Profile v3 adds channel-aware scoring; Profile v2 remains general-channel compatible.
9
+
10
+ ## Usage
11
+
12
+ ```text
13
+ hyv score draft.md profile.json heldout-a.md heldout-b.md heldout-c.md [--channel=email|chat|long-form|social|docs|general]
14
+ ```
15
+
16
+ ## Behavior
17
+
18
+ - Use only writing the owner has authorized and retain no new samples or telemetry.
19
+ - Keep profile-building and held-out samples separate. Do not relabel a different channel to force a score.
20
+ - HYV abstains when there are too few usable held-out samples, language confidence is insufficient for its English-oriented metrics, or the channel conflicts with the profile. Report that abstention rather than treating it as a failure or a score.
21
+ - The result includes component similarity and the writer's own pairwise range. A high score is not proof that the candidate was written by the person.
22
+ - This command is read-only. It does not call a provider, change a draft, or write a profile.
23
+
24
+ ## Handoff
25
+
26
+ Use `hyv-rewrite-prompt` for a bounded external editing brief, then `hyv-verify` for candidate verification. Re-run this score only with the same explicit held-out set when comparing drafts.
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-score",
4
+ "title": "hyv-score",
5
+ "description": "Score a draft against an explicit held-out local writing band.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Held-out voice evaluator",
8
+ "workflow_phase": "verify",
9
+ "input": {
10
+ "required": ["draft path", "profile path", "three or more held-out sample paths"],
11
+ "optional": ["--channel=email|chat|long-form|social|docs|general"]
12
+ },
13
+ "output": { "required": ["local held-out score report"], "optional": [] },
14
+ "evidence_requirements": [
15
+ "Report the returned band disposition and abstentions exactly; it is not an authorship claim.",
16
+ "Do not replace held-out samples with profile-building samples or claim a result when language confidence is insufficient."
17
+ ],
18
+ "permissions": ["execute_commands", "read_repository"],
19
+ "stop_conditions": [
20
+ "Stop when fewer than three held-out samples are supplied, the selected channel conflicts with the profile, or the score abstains."
21
+ ],
22
+ "tool_free_mode": {
23
+ "available": true,
24
+ "behavior": "Provide the exact command and state that local score execution is NOT_RUN; never invent a score.",
25
+ "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"]
26
+ },
27
+ "handoff_to": ["hyv-rewrite-prompt", "hyv-verify"]
28
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Score"
3
+ short_description: "Score a draft against an explicit held-out local writing band."
4
+ default_prompt: "Use $hyv-score to score a draft against three or more held-out local samples without making an authorship claim."
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: hyv-strict-check
3
+ description: Run the local strict AI-pattern and calibrated voice-match gate.
4
+ ---
5
+
6
+ # hyv-strict-check
7
+
8
+ Run the opt-in strict local quality gate without changing the draft, profile, or learning state.
9
+
10
+ ## Usage
11
+
12
+ ```text
13
+ hyv strict-check draft.md profile-v3.json sample-a.md sample-b.md sample-c.md sample-d.md sample-e.md
14
+ ```
15
+
16
+ ## Behavior
17
+
18
+ - Requires a Profile v3 built from at least five samples, five or more local validation samples, 1,500 validation-sample words, no duplicate samples, a consistent visible format baseline, and calibrated fingerprint tolerances.
19
+ - Returns `strict-ready`, `needs-human-review`, or `blocked` as JSON and exits `0` only for `strict-ready`.
20
+ - `blocked` covers missing strict evidence, configured blocking AI patterns, hard calibrated fingerprint drift, red VoiceDNA findings, and unresolved hidden text.
21
+ - `needs-human-review` keeps advisory and judgment-required AI patterns visible. It is not a clean result.
22
+ - It remains local-first and never sends samples or drafts to a provider.
23
+
24
+ ## Handoff
25
+
26
+ Fix only the named finding, then rerun the command. Do not rewrite unflagged text or promote any edit into learning from this command. Only after `strict-ready`, run hyv-final-check on the exact text that will be delivered; that final output boundary remains required after any later edit or formatting step.
@@ -0,0 +1,33 @@
1
+ {
2
+ "schema_version": "1.0.0",
3
+ "id": "hyv-strict-check",
4
+ "title": "hyv-strict-check",
5
+ "description": "Run the local strict AI-pattern and calibrated voice-match gate.",
6
+ "instruction_file": "SKILL.md",
7
+ "role": "Strict quality gate",
8
+ "workflow_phase": "verify",
9
+ "input": {
10
+ "required": ["draft path", "Profile v3 path", "at least five local writing-sample paths"],
11
+ "optional": []
12
+ },
13
+ "output": {
14
+ "required": ["strict-ready, needs-human-review, or blocked report"],
15
+ "optional": []
16
+ },
17
+ "evidence_requirements": [
18
+ "Report the exact local result, including readiness and every blocking or review finding.",
19
+ "Never call strict-ready a fact, authorship, or publication verdict.",
20
+ "Treat a mixed-format baseline or a profile built from fewer than five samples as blocked evidence."
21
+ ],
22
+ "permissions": ["execute_commands", "read_repository"],
23
+ "stop_conditions": [
24
+ "Stop when a Profile v3, enough samples, or calibrated metric tolerances are missing.",
25
+ "Stop when the result is blocked or needs human review; do not change the draft or learning state."
26
+ ],
27
+ "tool_free_mode": {
28
+ "available": true,
29
+ "behavior": "Provide the required inputs and explain that no strict result was run.",
30
+ "unavailable_statuses": ["NOT_AVAILABLE", "NOT_CONFIGURED", "NOT_RUN", "STALE", "ERROR"]
31
+ },
32
+ "handoff_to": ["hyv-final-check"]
33
+ }
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Hyv Strict Check"
3
+ short_description: "Run strict local AI-pattern and voice-match checks."
4
+ default_prompt: "Use $hyv-strict-check to run a strict local quality check on this draft."
@@ -21,4 +21,4 @@ hyv verify original.md candidate.md profile.json [writing-brief.json]
21
21
 
22
22
  ## Handoff
23
23
 
24
- Run `hyv verify` directly to execute the operation. Follow-on agents: hyv-lifecycle.
24
+ Run `hyv verify` directly to execute the operation. If the candidate must satisfy the strict AI-pattern and voice-match policy, run hyv-strict-check before any lifecycle handoff. A passing verify report does not substitute for strict-ready. Follow-on agents: hyv-strict-check, hyv-lifecycle.
@@ -44,6 +44,7 @@
44
44
  ]
45
45
  },
46
46
  "handoff_to": [
47
+ "hyv-strict-check",
47
48
  "hyv-lifecycle"
48
49
  ]
49
50
  }