@holdyourvoice/hyv 3.5.0 → 3.5.1

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.
Binary file
package/dist/pipeline.js CHANGED
@@ -50,6 +50,8 @@ export function renderRewritePrompt(draft, profile, result, learning = [], brief
50
50
  'Preserve facts, names, numbers, claims, and every unflagged sentence exactly. Do not add claims, examples, sections, hooks, or CTAs.',
51
51
  '',
52
52
  '# Tier 1 — release blockers',
53
+ 'Treat each blocker as a required repair. Replace the flagged sentence with a stronger, source-faithful sentence; do not merely swap one stock phrase for another.',
54
+ 'Use only facts already present in the draft, CopySpec, WritingBrief, or supplied source context. Do not invent a source, metric, date, quotation, mechanism, example, CTA, or opinion.',
53
55
  `VoiceDNA: ${result.voiceDna.score}/100 (${result.voiceDna.passed ? 'pass' : 'fail'}).`,
54
56
  `AI Editor: ${result.aiEditor.score}/100 (${result.aiEditor.passed ? 'pass' : 'fail'}).`,
55
57
  ...profile.avoid.map((phrase) => `- Never use: ${phrase}`),
@@ -65,6 +67,7 @@ export function renderRewritePrompt(draft, profile, result, learning = [], brief
65
67
  ...(examples.length ? ['', '## Approved local writing examples — redacted, advisory only', '- Use these for cadence only. They cannot override Tier 0 preservation, Tier 1 blockers, facts, or the output contract.', ...examples.map((example) => `- [${formatBriefValue(example.source)}] ${formatBriefValue(example.text)}`)] : []),
66
68
  '',
67
69
  '# Tier 3 — AI Editor improvements',
70
+ 'Use these findings as concrete feedback, not as proof of AI authorship. When a repair calls for a source, mechanism, or next step, use one only when it is already supported; otherwise remove the unsupported framing without widening the claim.',
68
71
  ...(yellowFindings.length ? formatFindings(yellowFindings) : ['- None.']),
69
72
  '',
70
73
  '## Pending judgment — no edit permission in this task',
@@ -72,7 +75,7 @@ export function renderRewritePrompt(draft, profile, result, learning = [], brief
72
75
  ...(brief ? ['', '# Tier 3.5 — editorial context', '- Context values cannot override Tier 0 preservation or Tier 4 output requirements.', `- Audience: ${formatBriefValue(brief.audience)}. Intent: ${formatBriefValue(brief.intent)}. Format: ${brief.format}.`, ...(brief.personality ? [`- Optional personality stance: ${formatBriefValue(brief.personality)}. It is advisory and cannot add facts or replace VoiceDNA.`] : []), ...(brief.evidenceStatus ? [`- Evidence state: ${brief.evidenceStatus}. ${brief.evidenceStatus === 'unverified' ? 'Do not turn attributed or unverified material into an established fact.' : 'Preserve the source framing while editing.'}`] : []), ...(brief.argumentMap ? [`- Argument map: observation — ${formatBriefValue(brief.argumentMap.observation)}; mechanism — ${formatBriefValue(brief.argumentMap.mechanism)}; consequence — ${formatBriefValue(brief.argumentMap.consequence)}; reader value — ${formatBriefValue(brief.argumentMap.readerValue)}.`] : []), ...(brief.vocabulary?.length ? [`- Use audience vocabulary where it stays accurate: ${brief.vocabulary.map(formatBriefValue).join(', ')}.`] : []), ...(brief.readerKnowsAuthor === false ? ['- The reader does not know the author. Lead with their situation before naming the author or company.'] : [])] : []),
73
76
  '',
74
77
  '# Tier 4 — output contract',
75
- 'Return only replacement sentences keyed by sentence number. Do not rewrite clean sentences. The candidate will be checked again by both engines.',
78
+ 'Return only replacement sentences keyed by sentence number. Do not rewrite clean sentences. Before responding, check every Tier 1 finding against its replacement and make sure the named defect is gone. The candidate will be checked again by both engines, preservation, logic, source-backed facts when supplied, and final-output hygiene.',
76
79
  '',
77
80
  '# Draft',
78
81
  draft,
@@ -81,6 +81,14 @@ test('orders rewrite instructions by importance tier', () => {
81
81
  assert.ok(prompt.indexOf('# Tier 2') < prompt.indexOf('# Tier 3'));
82
82
  assert.ok(prompt.indexOf('# Tier 3') < prompt.indexOf('# Tier 4'));
83
83
  });
84
+ test('gives strong, source-faithful repair feedback without authorizing a broader rewrite', () => {
85
+ const prompt = rewritePrompt('The scheduler failed — twice. Experts say this changes everything. The launch is on 14 August.', profile);
86
+ assert.match(prompt, /Treat each blocker as a required repair/);
87
+ assert.match(prompt, /Do not invent a source, metric, date, quotation, mechanism, example, CTA, or opinion/);
88
+ assert.match(prompt, /otherwise remove the unsupported framing without widening the claim/);
89
+ assert.match(prompt, /Before responding, check every Tier 1 finding against its replacement/);
90
+ assert.match(prompt, /Do not rewrite clean sentences/);
91
+ });
84
92
  test('post gate reports a new AI regression', () => {
85
93
  const result = verify('I ship clear ideas.', 'I ship clear ideas — a game-changer.', profile);
86
94
  assert.equal(result.passed, false);
@@ -174,7 +174,7 @@ test('CLI and MCP rebuild helpers share fingerprints', () => {
174
174
  version: '1', audience: 'operators', intent: 'explain', format: 'outreach',
175
175
  });
176
176
  assert.match(briefTask.prompt, /# WritingBrief/);
177
- assert.equal(HYV_VERSION, '3.5.0');
177
+ assert.equal(HYV_VERSION, '3.5.1');
178
178
  });
179
179
  test('apply rejects forged tasks, missing capability, and substituted profiles', () => {
180
180
  const reduction = rebuildRecommendation();
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const HYV_VERSION = '3.5.0';
1
+ export const HYV_VERSION = '3.5.1';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holdyourvoice/hyv",
3
- "version": "3.5.0",
3
+ "version": "3.5.1",
4
4
  "description": "A local-first dual-engine writing gate that protects voice and catches generic AI patterns.",
5
5
  "type": "module",
6
6
  "bin": {