@chrono-meta/fh-gate 1.4.78 → 1.4.80

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.
@@ -11,13 +11,13 @@
11
11
  "plugins": [
12
12
  {
13
13
  "name": "fh-meta",
14
- "version": "1.4.78",
14
+ "version": "1.4.80",
15
15
  "description": "Hub meta-operations toolkit — 35 skills + 7 agents. New in 1.4.53: `fh-codex-doctor` (npm bin) — Codex adapter drift scanner; reads the documented M1/M2/M3 skill tier map + skill/agent source and reports codex-native/adapter-required/claude-native/unclassified per unit, wired into `npm test`/`prepublishOnly` (fail-closed on unclassified Claude-native primitives). New in 1.4.49: steel-quench gains Step 0.6 Verdict-Invariance Probe (groundedness axis — a load-bearing judged gate's verdict must track behavior, not rubric phrasing; measured flip-count over cross-family paraphrases; arXiv:2605.06161 Policy Invariance anchor); multi_model_sidecar_strategy §Vendor-native harness (a model is strongest in its own vendor CLI — Claude/CC, GPT/codex, Gemini/Antigravity; a universal router degrades all of them, so it stays an autocomplete/QA sidecar, never orchestration); predelete_check.sh fail-closed rewrite; memory-hygiene A-TMA anchor. New in 1.4.48: phantom-quench + steel-quench gain external frontier anchors (arXiv:2607.02052 package-hallucination; arXiv:2607.02057 prompt-coverage-adequacy); README model-flat claim reframed from a per-release point-curve to structural invariants (operation flattens across tiers; depth tier-order fixed within a generation). New in 1.4.47: onboarding step ① surfaces the Mode D companion-store session-start load in the auto-read salience anchor (previously only in the local binding + rules, so a greeting could skip the load). New in 1.4.46: context-doctor command-output axis (route to rtk/proxy for verbose CLI stdout, complementing .claudeignore; risk-gated to token-scarce envs). New in 1.4.41: context-doctor 2026 trigger vocab (context engineering/rot/collapse) + phantom-citation hardening; hub measurement-integrity-checklist (cross-model measurement pre-flight: display-name pin/reps≥3/discriminating probe). New in 1.4.40: install-wizard queryable-wiki scaffold (INDEX + session-start read + R/W/C ingest). New in 1.4.39: auto-decorrelation (cross-family verifier sidecar recruitment) + video-ingest (capability-routed video ingestion). New in 1.4.x: verify-axis check-class taxonomy (mandatory-pass/measured/judged), no-reinvention Tier-0 inventory, 7-class failure taxonomy, Destructive-Op Gate, Wave-T (Temper), tier-floor governance, Mode D Model Notice, FC consent lane, default-Sonnet guidance. New in 1.3.0: public-surface-audit, field-harvest Mode B auto-trigger, 4-axis gate scope ext. Validated cross-CLI: Claude Code, Codex, Gemini.",
16
16
  "source": "./plugins/fh-meta"
17
17
  },
18
18
  {
19
19
  "name": "fh-commons",
20
- "version": "1.4.78",
20
+ "version": "1.4.80",
21
21
  "description": "Project-agnostic utility skills — 4 skills (convergence-loop · deliberation · mcp-circuit-breaker · token-budget-gate) + 1 agent (quench-challenger). Domain-independent utilities transplantable into any project.",
22
22
  "source": "./plugins/fh-commons"
23
23
  }
package/CLAUDE.md CHANGED
@@ -531,7 +531,7 @@ Proposal format: `"I see [X]. Want me to run /[skill] to [one-line description]?
531
531
  | **"진단해줘", "개선해줘", "diagnose this", "improve this harness", "check this project", "audit this project"** — said while working **in a mapped project** (not a single-file ask) | **Field-Harness Diagnostic** (see §Field-Harness Diagnostic above → compose existing checks into one ranked M/S/R list → HITL approval per item, nothing auto-fixed) |
532
532
  | **"새 프로젝트", "하네스 작성해줘", "이 프로젝트 가속화", "harness-ify this", "accelerate this project"** — an onboarding/acceleration door (returning-menu ①②③) | **Onboarding / Acceleration Autopilot** (see §Onboarding / Acceleration Autopilot above → Phase 0 auto-discover + branch → innovator-centered recommend → ranked install plan → HITL per item, non-overwriting; "끝까지 자율로" → full-autonomy under /goal-quench gate) |
533
533
 
534
- **Guard**: Do not propose a skill that is already running. One signal = one-line proposal (no pressure). Before proposing, consult the UAP (§Operational Adaptation Loop): a skill the user has rejected 3+ times is **suppressed**, not re-proposed.
534
+ **Guard**: Do not propose a skill that is already running. One signal = one-line proposal (no pressure). Before proposing, consult the UAP (§Operational Adaptation Loop): a skill the user has rejected 3+ times is **suppressed**, not re-proposed — and, symmetrically, a class **accepted 3× consecutively** earns a one-time "stop asking?" offer (§Consent promotion; never on irreversible surfaces).
535
535
  For per-skill utterance patterns, see the relevant `SKILL.md §Trigger Phrases` section.
536
536
 
537
537
  ### Cadence Rules — Check at Session Start
@@ -564,7 +564,8 @@ Some proposals are not *time*-overdue — they fire **once when a specific work
564
564
  Self-healing is not only FH-self-dev (Mode D 4-axis) and reactive (`verify-bidirectional`). A **standing, per-user operational loop** tunes FH behavior to the individual during normal field use, and escalates **only generalizable** learnings to the `field-harvest` → FH-origin PR funnel — idiosyncratic taste stays local (drift guard).
565
565
 
566
566
  - **User Adaptation Profile (UAP)** — `tracks/_meta/user_adaptation_profile.md` (local/gitignored; **behavioral prefs only, never domain content**). Records skill-proposal outcomes (`accepted`/`rejected`/`sustained` — same vocabulary as `operations.md`), preferred tier/language/cadence, recurring friction, muted nags.
567
- - **Pass** — rides `field-harvest` Mode B at field-session close (no new trigger, one per session): READ to apply (suppress a 3×-rejected proposal, default to preferred tier, mute declined cadence nags), WRITE to update outcomes.
567
+ - **Pass** — rides `field-harvest` Mode B at field-session close (no new trigger, one per session): READ to apply (suppress a 3×-rejected proposal, **offer standing consent on a 3×-accepted class**, default to preferred tier, mute declined cadence nags), WRITE to update outcomes.
568
+ - **Consent promotion (accept-side)** — repeated approval must offer to stop asking, not bill the same prompt forever: 3 consecutive `accepted` on a **registered** class (`tracks/_meta/consent_classes.yaml` — classes are declared, never minted mid-run) → **offer once, quoting the three approvals and the exact scope** → granted = a **time-limited lease**, revocable, and every unprompted run announces itself. **Not symmetric with suppression**: a bad suppression costs a re-ask, a bad grant has side effects. **Floor, decided mechanically from the registry — never by the session's own judgment**: a class never promotes if its sinks are irreversible (publish · delete · history-rewrite), if it *feeds* such a sink (**taint propagates through reversible steps**), or if that is **unknown** — unknown is not reversible. No UAP / no registry entry / expired → keep asking (absent ≠ granted). **Named residual: the ledger is self-attested** — mitigated (append-only, quoted evidence), not closed.
568
569
  - **Generalization gate** — idiosyncratic → UAP local; generalizable (any user benefits; `≥40%` reject = redefine candidate / `≥60%` accept = reinforce, per `operations.md` gate) → `field-harvest` Mode A → FH PR (HITL).
569
570
  - **Ephemeral guard** — UAP is gitignored, wiped on cloud reclaim; in ephemeral sessions operate from defaults, do not fabricate it.
570
571
 
@@ -699,6 +700,10 @@ Closing phrase detected ("wrap up", "done", "good work", "end session", etc.)
699
700
  outcomes. ⑤ is ATOMIC and owns BOTH writes: (a) append any close-time finding to
700
701
  `fh_completed_{date}.md` FIRST, (b) then write the card. Once ⑤ starts, `fh_completed`
701
702
  is CLOSED — a later append re-opens the violation ⑤ exists to prevent.
703
+ **Late finding (named case)**: a finding that surfaces AFTER (b) — including while writing
704
+ the final message to the operator — means ⑤ is **not done**. Re-run ⑤ **whole**: append,
705
+ then **rewrite the card**. Appending alone is the violation; the card must never be older
706
+ than `fh_completed`.
702
707
  → ⑥ Commit card + push
703
708
  ```
704
709
 
@@ -67,7 +67,7 @@ instrument: the next slip finds its leg pre-diagnosed.
67
67
  | Backlog item | Fires when (measured trigger) |
68
68
  |---|---|
69
69
  | ~~Close-chain ordered-checklist script~~ | **BUILT 2026-07-10** (`scripts/session_close_check.sh`) — operator strengthen-instruction; the miss class (card staleness) was already measured, only the build trigger was overridden (recorded, not silent) |
70
- | Weekly-audit scaffold + data-gather script | a weekly audit missed or hand-gathered wrong window data |
70
+ | Weekly-audit scaffold + data-gather script — **TRIGGER FIRED 2026-07-31, half built** | a weekly audit missed or hand-gathered wrong window data. **It fired on both legs**: the audit was **50 days** overdue (cadence is 7), and the window data was then gathered by hand with an ad-hoc bucketing script written on the spot. What was built in response is the **detection** half only — a cadence line in the SessionStart hook, mirroring the frontier-digest one, because the diagnosis was that the two cadences differ in *instrumentation*, not in importance: the mechanized one went 50 days without missing a day while this one went 50 days unnoticed. The **scaffold + data-gather** half stays unbuilt on purpose; a missed audit is now visible, and whether hand-gathering is painful enough to mechanize is a second measurement, not an implication of the first. Re-fires if the next audit is again hand-gathered with friction worth recording. |
71
71
  | harvest-loop Step 0-b/0-c evidence check | a harvest run misses completed items despite `fh_completed_*` existing |
72
72
  | goal-quench mid-run checkpoint files (70/85/95%) | a /goal run blows through a threshold unnoticed |
73
73
  | ~~Substrate-jump detector~~ | **BUILT 2026-07-10** (`scripts/substrate_jump_detector.sh`, SessionStart-wired) — same operator instruction; structure-enforcing class (out-of-context drift), permanent per the durable-mechanization criterion |
@@ -28,9 +28,150 @@ This loop fills that gap. It is deliberately thin: it **reuses** existing parts
28
28
 
29
29
  Runs at field-session close, **riding `field-harvest` Mode B** — no new trigger, never an interception. One pass per session.
30
30
 
31
- - **READ** (session start / proposal time): apply UAP — suppress a skill proposal rejected 3+ times (an `accepted` record carries **no** positive auto-action — the skill simply stays surfaced; do not auto-run on acceptance), default to the preferred tier, mute cadence nags the user always declines, and **apply capability-escalation consent** (`sidecar_consent`/`floorup_consent` `declined` → route to the Sonnet / Tier-3 floor, recommend-only, no re-nag; `unset` → ask-once at first need per the consent protocol). (Tier note: the UAP tier default is a session-depth setting; the Mode D model notice is model-only + advisory and never overrides it.)
31
+ - **READ** (session start / proposal time): apply UAP — suppress a skill proposal rejected 3+ times, apply any **standing consent** granted per §Consent promotion below (an `accepted` record on its own still carries **no** positive auto-action — acceptance alone never auto-runs anything; only a granted standing consent does), default to the preferred tier, mute cadence nags the user always declines, and **apply capability-escalation consent** (`sidecar_consent`/`floorup_consent` `declined` → route to the Sonnet / Tier-3 floor, recommend-only, no re-nag; `unset` → ask-once at first need per the consent protocol). (Tier note: the UAP tier default is a session-depth setting; the Mode D model notice is model-only + advisory and never overrides it.)
32
32
  - **WRITE** (session close): update outcome counts + new friction points.
33
33
 
34
+ ## Consent promotion (accept-side) — repeated approval must offer to stop asking
35
+
36
+ The suppression rule above is **one-directional**: repeated *rejection* changes FH's behavior, repeated
37
+ *approval* changed nothing, so a user who approves the same class every time keeps paying the same
38
+ prompt forever. That asymmetry is the defect this section closes. It is the general-user form of the
39
+ elastic-granularity principle already granted to the operator (`feedback_hitl_elastic_granularity_cto`):
40
+ **the floor is fixed, the approval grain is not.**
41
+
42
+ **Promotion is not the mirror image of suppression.** Rejection suppresses a *proposal* — a wrong
43
+ suppression costs one manual re-ask. Acceptance authorizes an *action* with the user absent — a wrong
44
+ grant has side effects. Symmetric machinery over asymmetric stakes is itself the error (cross-family
45
+ review, 2026-07-29). So the accept side carries three things the reject side does not: an **explicitly
46
+ scoped** class, an **expiry**, and a **separate confirmation** that is not the same "yes" that approved
47
+ the action in front of the user.
48
+
49
+ **Classes are declared, never minted at runtime** (this is what makes the trigger mechanical). A class
50
+ is promotion-eligible only if it exists in the **consent-class registry**, `tracks/_meta/consent_classes.yaml`,
51
+ declaring: `owner` (gate/skill) · `mode` · `target scope` · `capabilities` (read / local-write /
52
+ network / dispatch / repo-mutation) · `sinks` (what downstream surface the action can reach). A session
53
+ may **propose** a registry entry (HITL, like any asset) but may **not** invent one mid-run and start
54
+ counting against it. *Origin: without a registry the guard below did not bind — the class could simply
55
+ be recorded over-broad at birth (`sim-conductor` rather than `dispatch read-only sim on a local
56
+ artifact`), and no after-the-fact widening rule can catch a class that was born wide.*
57
+
58
+ **Registry authorship is itself a capture surface** (cross-family round 2): closing runtime minting
59
+ still leaves the agent drafting a broad entry, framing it as housekeeping, and later enjoying the
60
+ approved breadth. So a proposed entry is promotion-eligible only after it carries (a) an explicit
61
+ `excludes:` list of neighbouring actions the class must **not** cover, (b) 2+ **adversarial examples** —
62
+ concrete actions a reader might assume are inside and that the author asserts are outside — and (c) a
63
+ review by something other than the proposing session (the human, or a cross-family auditor). A class
64
+ definition is reviewed as a **grant of future autonomy**, not as a config row.
65
+
66
+ **Storage form (operator decision 2026-07-31)**: `standing_consent` — and every other machine-read UAP
67
+ field — lives in the UAP's **YAML frontmatter**, the `---` block at the top of the file, parsed whole by
68
+ the canonical loader. **Prose in the body is never read by a script**, and a grant written there is a
69
+ **fail-closed error**, not an absence: an unread grant is not an absent one. Why the form changed: the
70
+ previous reader line-sliced a `standing_consent:` key out of markdown, and each special case it closed
71
+ opened the next (loader-identity → nested key → explicit-key → comment-vs-heading, three in one day).
72
+ The root was storing a machine field in markdown, where `#` and indentation mean different things to
73
+ the two languages; frontmatter removes the slicing *decision*, because "the first `---` block" has one
74
+ referent. Record the human-readable grounds in the body, the value in the frontmatter.
75
+
76
+ **Mechanical floor**: `scripts/consent_registry_check.sh` — joins `standing_consent` against the
77
+ registry and enforces schema, eligibility soundness (a class naming an irreversible or unlisted sink
78
+ **cannot** declare itself promotable), registration, expiry, and recorded scope. Missing registry → N/A
79
+ + promotion disabled; unparseable → fail-closed. Run it before trusting any grant; the prose above is
80
+ the salience layer over this check, not the enforcement. Anchor: `scripts/test_consent_registry.sh`
81
+ (64 lanes, incl. the `F*` storage-form lanes). Four mutants were run against it — each false-clean
82
+ net, the fence regex, and the falsy-laundering guard — and each turned its lanes red, so the green is
83
+ measured rather than assumed. Cross-family review found the first draft's green was partly vacuous
84
+ (one lane called `ok` in both branches; three others passed via a path other than the one they named).
85
+
86
+ **Trigger**: the same registered class recorded `accepted` **3 consecutive times**, counted across
87
+ sessions from the UAP outcome log. Refinements that keep the count honest:
88
+ - *Consecutive* means consecutive **within that class's own entries**; other classes interleaved do not
89
+ break the streak, a single `rejected` or `modified` does. An approval the user altered before granting
90
+ is logged `modified`, never `accepted`.
91
+ - **Only a promotion-eligible approval prompt counts** — one user gesture, one entry. **Retries of the
92
+ same operation count once**, and one "yes, do those three" is **one** approval, not three. Ordinary
93
+ supervised retry ("응, 다시 해봐" ×3) is not durable consent and must never reach the threshold.
94
+ - The running count is **visible to the user at each approval** (`1/3` · `2/3` · `3/3`), so the offer is
95
+ never the first time they learn a streak was being tallied.
96
+
97
+ **Action — offer once, with the evidence in the offer**:
98
+
99
+ > "`<class>` 을 3번 연속 승인했다 (`<date1>`, `<date2>`, `<date3>` — 각각 `<one-line what was approved>`).
100
+ > 범위: `<mode · target · capabilities · sinks>`. 앞으로 `<N>`일간 안 묻고 진행할까?
101
+ > (언제든 '다시 물어봐')"
102
+
103
+ The offer **quotes the three approvals and the exact scope**; a grant the user cannot audit is not
104
+ consent. Then:
105
+
106
+ - **granted** → write `standing_consent: <class>: {granted: <date>, expires: <date+N>, effects: [...]}`.
107
+ Later instances run unprompted, each **states in one line what it did**, and each **appends a durable
108
+ entry to `tracks/_meta/consent_runs.log`**. *Post-action chat notice is not a control* (cross-family
109
+ round 2): a line the user scrolls past has stopped the prompt without replacing it. The chat line is
110
+ courtesy; the log is the audit surface, and it is the reason standing consent may cover only actions
111
+ that are **recoverable and locally reviewable** — an unrecoverable action was already excluded by the
112
+ floor, and an unreviewable one is excluded here.
113
+ **Expiry is not optional** — at expiry the consent lapses to `unset` and the class is asked again;
114
+ standing consent is a renewable lease, not a transfer of the decision.
115
+ - **declined** → write `declined`. **Never ask again for that class version** — the same no-re-nag rule
116
+ as muted cadence reminders. *Scoped to the version, not forever*: a user may decline because the
117
+ timing was wrong, and permanent suppression with no renewal path is its own defect. A re-offer is
118
+ allowed only when the class is **materially narrowed** (a new registry version with strictly smaller
119
+ scope) or the user asks. Re-offering the same scope is a nag.
120
+ - Revocation is always available and never negotiated: "다시 물어봐" / "revoke" → `unset`.
121
+
122
+ **Floor — what never promotes (규약; this is the whole constraint)**: promotion is available only where
123
+ the *protocol still passes*. Applicability is decided **mechanically, from the registry entry — never by
124
+ the running session's judgment**, because the session that wants to stop being asked is the worst
125
+ possible arbiter of whether it may. A class never promotes, at any count, when:
126
+
127
+ 1. its `sinks` include an **irreversible surface** — publish / go-public, delete, history-rewrite, or any
128
+ surface guarded by a fail-closed Irreversibility gate (`CLAUDE.md §Irreversibility Gates`); **or**
129
+ 2. it **feeds, queues, or enables** such a sink even though it does not itself cross one — **sink
130
+ tainting**. Reversible steps compose into irreversible outcomes: "edit workflow config" + "write
131
+ release notes" + "create local commit" are each locally reversible, and a CI workflow publishes the
132
+ result. Taint propagates along that chain; the floor is inherited, not re-derived per step; **or**
133
+ 3. its irreversibility is **unknown or not yet classified** → **no promotion, ask**. Unknown is not
134
+ reversible. (An unregistered class is by definition unknown, which is why 1–3 collapse to a single
135
+ mechanical test against the registry.)
136
+
137
+ Their cost is not the prompt, it is that the thing cannot be undone — grain-independent by construction.
138
+ **The promotion offer itself is HITL**: this section grants no path to auto-approval the user did not
139
+ answer "yes" to once, knowingly and in scope, which is why it does not contradict the "acceptance alone
140
+ never auto-runs" rule above.
141
+
142
+ **Degrade direction (fail-closed), three ways**: no UAP (ephemeral/cloud session, wiped profile) → **no
143
+ promotion, keep asking**. No registry entry → **no promotion, keep asking**. Expired or unparseable
144
+ record → **`unset`, keep asking**. A missing consent record is never `granted` — an absent measurement is
145
+ not a yes.
146
+
147
+ **Named residual — the ledger is self-attested (cross-family, 2026-07-29, HIGH, NOT closed).** The UAP
148
+ outcome log is written by the same agent that benefits from fewer prompts, and it is gitignored, so there
149
+ is no ordinary review trail. Nothing in this section fixes that; the honest mitigations only *narrow* it:
150
+ consent events are **append-only** (an entry is superseded, never edited or deleted), the offer must
151
+ **quote the three approvals verbatim** so a user can catch a fabricated streak at the one moment it
152
+ matters, and every unprompted run **announces itself**. A real fix requires the consent record to be
153
+ produced by the approval channel rather than by the consuming agent — outside this rule's reach. **Until
154
+ then, treat every standing consent as auditable-by-the-user-only, and never widen the mechanism's scope
155
+ on the assumption the ledger is trustworthy.**
156
+
157
+ **Consent binds to the action's SHAPE, not its label** (found by blind target-tier sim, 2026-07-29):
158
+ a class name is a string, and the action behind it can change after consent is granted. A sim that
159
+ merely returned a report when you said "stop asking" may, ten sessions later, write into shared memory
160
+ and trigger a downstream commit — same label, different blast radius, HITL skipped. So a grant records
161
+ **what it was granted for**: the owning gate/skill, and the set of **effect classes** the action had at
162
+ grant time (reads · local writes · network · dispatch · repo-mutation) **plus the `target` scope and
163
+ the `sinks` fingerprint**. On any later run whose fingerprint is **not a subset** of the granted one,
164
+ standing consent **reverts to `unset` and asks again**, naming what widened. Effect classes alone are
165
+ too coarse to be the whole test (cross-family round 2): "local write" stays "local write" whether the
166
+ target is a scratch report or a policy file — the *target* is where that drift shows, which is why it
167
+ is part of the fingerprint and not merely descriptive. Widening is the trigger; narrowing is not. This is the same discipline as the
168
+ byte-identity anchors used elsewhere: consent is pinned to a fingerprint, not to a name, because
169
+ **the name is exactly what does not change when the danger does.**
170
+
171
+ **Guard against class inflation**: the class recorded is the *narrow* one that was actually approved
172
+ 3×, never a widened parent. Three approvals of "dispatch a Sonnet sim" do not grant "dispatch any
173
+ agent" (`feedback_scope_widening_needs_grounding` — widening judgments get no free pass).
174
+
34
175
  ## Generalization gate → reverse-PR funnel
35
176
 
36
177
  This is the operator's **"원본 반영 가치"** criterion made mechanical. Split each UAP learning:
@@ -46,6 +187,8 @@ This is the operator's **"원본 반영 가치"** criterion made mechanical. Spl
46
187
 
47
188
  - **UAP WRITE ran** at field-session close (or was correctly skipped — absent profile / ephemeral session). *Check class: mandatory-pass (binary — did Step 5-B.1 execute or log a skip reason).*
48
189
  - **UAP READ applied** at session start / proposal time when a profile exists (preferred tier defaulted, 3×-rejected proposals suppressed, declined cadence nags muted). *Check class: judged, pair: the target-tier blind sim below.*
190
+ - **A class at 3 consecutive `accepted`** was either offered promotion once, or correctly not offered with the reason recorded (irreversible surface · already `declined` · no UAP). *Check class: measured — the consecutive count is read off the UAP outcome log, not recalled.*
191
+ - **Every `standing_consent` key resolves to a registry entry whose `sinks` are irreversible-free, and is unexpired.** *Check class: mandatory-pass (binary — join `standing_consent` keys against `consent_classes.yaml`, reject any key that is unregistered, taint-reachable to an irreversible sink, or past `expires`; any hit is a defect, not a judgment call).*
49
192
  - **No domain content** entered the UAP this session. *Check class: judged, pair: phantom/content scan of the UAP diff.*
50
193
 
51
194
  ## Guards
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chrono-meta/fh-gate",
3
- "version": "1.4.78",
3
+ "version": "1.4.80",
4
4
  "description": "FH runtime adapters — run FH governance, skills, and agents via Claude or Codex with machine-parseable gates.",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -64,6 +64,7 @@
64
64
  "scripts/count_check.sh",
65
65
  "scripts/selfcheck.sh",
66
66
  "scripts/package_coverage_check.sh",
67
+ "scripts/test_package_coverage_lanes.sh",
67
68
  "scripts/test_fh_gate_regressions.sh",
68
69
  "templates/local_fh_context.md",
69
70
  "docs/ETHOS.md",
@@ -107,6 +108,9 @@
107
108
  "scripts/memory_nearcheck.py",
108
109
  "scripts/sidecar_wait.sh",
109
110
  "scripts/test_sidecar_wait_stdin.sh",
111
+ "scripts/consent_registry_check.sh",
112
+ "scripts/test_consent_registry.sh",
113
+ "templates/consent_classes.yaml.example",
110
114
  "scripts/test_session_close_lanes.sh",
111
115
  "scripts/test_card_drift_probe.sh",
112
116
  "scripts/universal_guard_check.sh",
@@ -130,6 +134,12 @@
130
134
  "templates/settings.SessionStart.snippet.json",
131
135
  "scripts/test_node_check_lanes.sh",
132
136
  "scripts/sidecar_calibrate.sh",
133
- "scripts/test_sidecar_calibrate_lanes.sh"
137
+ "scripts/test_sidecar_calibrate_lanes.sh",
138
+ "scripts/pipe_verdict_guard.sh",
139
+ "scripts/test_pipe_verdict_guard_lanes.sh",
140
+ "templates/settings.PreToolUse.snippet.json",
141
+ "scripts/halffix_propagation_scan.sh",
142
+ "scripts/test_halffix_lanes.sh",
143
+ "scripts/test_ollama_panel_lanes.sh"
134
144
  ]
135
145
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-commons",
3
- "version": "1.4.78",
3
+ "version": "1.4.80",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fh-meta",
3
- "version": "1.4.78",
3
+ "version": "1.4.80",
4
4
  "engines": {
5
5
  "claudeCode": ">=1.0.0"
6
6
  },