From 0be9e774c3b5420eea5f19000205d15b283a3e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Przemys=C5=82aw=20Galarowicz?= Date: Wed, 12 Aug 2026 12:54:09 +0200 Subject: [PATCH] fix(pkg): mark pharn-oss private, drop the dead main entry point MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit package.json had no "private": true, so a real `npm publish` could push this whole methodology repo (.dev/, pharn/, .claude/) to the registry under the publishable name "pharn-oss" — the distributable npm package is the separate @pharn-dev/pharn (pharn-cli), never this repo. It also declared "main": "index.js", a file that has never existed, so the package presented itself as importable when it is neither publishable nor an entry point. Both edits are one axis: package.json currently claims a publish/import surface this repo doesn't have. private: true removes the surface; deleting main removes the dead pointer into it — bundled deliberately rather than split, since main's deletion has no meaning without the private context that explains why it was already dead. No SKILLS_VERSION bump: package.json is pure repo-meta per CLAUDE.md's versioning discipline, not shipped product-surface bytes. Co-Authored-By: Claude Sonnet 5 --- .dev/features/f8-package-private/GRILL.md | 83 ++++++++++++++++++ .dev/features/f8-package-private/PLAN.md | 34 ++++++++ .../features/f8-package-private/REGRESSION.md | 39 +++++++++ .dev/features/f8-package-private/REVIEW.md | 84 +++++++++++++++++++ .dev/features/f8-package-private/SHIP.md | 44 ++++++++++ .dev/features/f8-package-private/VERIFY.md | 32 +++++++ .../f8-package-private/regression-report.json | 21 +++++ .../f8-package-private/verify-report.json | 14 ++++ package.json | 2 +- 9 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 .dev/features/f8-package-private/GRILL.md create mode 100644 .dev/features/f8-package-private/PLAN.md create mode 100644 .dev/features/f8-package-private/REGRESSION.md create mode 100644 .dev/features/f8-package-private/REVIEW.md create mode 100644 .dev/features/f8-package-private/SHIP.md create mode 100644 .dev/features/f8-package-private/VERIFY.md create mode 100644 .dev/features/f8-package-private/regression-report.json create mode 100644 .dev/features/f8-package-private/verify-report.json diff --git a/.dev/features/f8-package-private/GRILL.md b/.dev/features/f8-package-private/GRILL.md new file mode 100644 index 0000000..f9fcd1b --- /dev/null +++ b/.dev/features/f8-package-private/GRILL.md @@ -0,0 +1,83 @@ +# GRILL — f8-package-private + +Plan under interrogation: `.dev/features/f8-package-private/PLAN.md`. + +**Spec-hash check:** recomputed `sha256(pharn/ARCHITECTURE.md)` = +`8f5ec002e3b18cbfd2f094b08a3671f7ed42a05a3fbaf01a11bbbd28da30fb52`, matches the plan's +`spec_content_hash` exactly. No drift. + +**Griller membership (floor, `pharn/floor/count-grillers.mjs`):** 13 registered +(`a11y, architecture, comprehension, coupling, documentation, error-handling, i18n, migrations, +observability, performance, privacy, security, testability`). All 13 applied below; this is advisory +end-to-end (fix #3) — nothing here gates `/pharn-dev-build`. + +## Findings + +```yaml +- type: FINDING + rule_id: P1 + severity: important + file: ".dev/features/f8-package-private/PLAN.md:1" + problem: "The plan declares no verification/acceptance approach for the change it makes — the '## Evals to write (P1)' section correctly says 'None' because package.json is not a Capability, but that answers a different question than 'how do we know the fix worked.'" + evidence: "## Evals to write (P1)\n\n- None — P1 (\"no Capability ships without evals\") governs `role:`-bearing Capabilities under `pharn/`. `package.json` carries no `role:` frontmatter and is not a Capability, so P1 does not apply to this increment." +``` + +```yaml +- type: FINDING + rule_id: P0 + severity: minor + file: ".dev/features/f8-package-private/PLAN.md:24" + problem: 'The guarantee audit correctly labels the npm-refusal behavior advisory (no PHARN floor primitive backs it), but does not name that this leaves no regression guard: a future edit could silently drop "private": true and nothing in `npm run check` would catch it.' + evidence: '"A real `npm publish` refuses once `private: true` is set" -> advisory (external system behavior). ... no PHARN-side hook, hash, or enum check enforces it.' +``` + +```yaml +- type: FINDING + rule_id: P3 + severity: minor + file: ".dev/features/f8-package-private/PLAN.md:19" + problem: 'The single ''## Files'' entry bundles two edits to package.json — adding "private": true (a publish-safety fix) and deleting the dead "main" field (a stale-reference cleanup) — under one stated axis; worth the human''s explicit confirmation these are one reason to change, not two glued together.' + evidence: '- package.json — add "private": true after "version"; delete the "main": "index.js" line — layer repo-meta' +``` + +```yaml +- type: FINDING + rule_id: P2 + severity: minor + file: ".dev/features/f8-package-private/PLAN.md:1" + problem: "The originating defect narrative frames this as preventing the repo from being 'shipped' via publish, which could read as a confidentiality fix; the repo is already public on GitHub, so the actual value of `private: true` is preventing npm-registry namespace confusion with the real `@pharn-dev/pharn` package, not secret exposure — worth precise phrasing in the commit message / CHANGELOG note." + evidence: '"A single `npm publish` would push the entire working tree -- .dev/, pharn/, .claude/, everything -- to the registry under that name."' +``` + +## Non-findings (checked, no concern) + +- **Documentation griller (P7):** no public/exported surface is added (`private`/`main` are npm-standard + package.json fields, not a new API or config key a downstream consumer reads) — genuinely needs no + dedicated documentation. Advisory-only observation: given this repo's own exhaustive CHANGELOG habit + (see the `[Unreleased]` F9 entry), the optional one-line note the plan allows is worth taking even + though not required. +- **Architecture griller (P3, Layer 2 fit):** correctly scoped outside the `pharn/` capability tree as + repo-meta; no architectural-fit concern. +- **Security griller (Layer 1, floor secret-literal scan):** no hardcoded secret or credential literal + in the plan text — clean. +- **Testability griller (Layer 2 adequacy):** N/A — Layer 1 already raised absence above; adequacy is + moot until a verification approach exists. +- **a11y, coupling, comprehension, error-handling, i18n, migrations, observability, performance, + privacy:** not applicable — no UI, no runtime code path, no cross-module coupling, no error-handling + surface, no user-facing text, no data migration, no metrics/logging surface, no perf-sensitive path, + no personal data. One JSON config file, two fields, zero behavior. + +## Summary + +The plan is small and well-scoped, and the spec→plan hash chain holds. The two live findings worth the +human's attention before build: (1) the plan doesn't declare how the fix will be verified beyond "re-run +the reproduce" implied by context — the build/verify stages will in practice confirm it via +`npm run check` + the plan's own verification checklist from the originating request, but that checklist +never made it into `PLAN.md`'s structure; (2) there is no durability guard against a future silent +regression of `private: true` — named here as a residual, not a recommendation to build a checker now +(P7: no trigger from a real dogfood/eval failure exists yet, the same reasoning `product-capability-catalog` +used to defer its own follow-up). The P3 bundling and P2 risk-framing notes are precision nits, not +blockers. + +**ADVISORY VERDICT: 4 concerns raised (0 blocking-severity, 1 important, 3 minor) — for the human to +weigh before `/pharn-dev-build`. This is not a pass/fail gate; `/pharn-dev-grill` blocks nothing.** diff --git a/.dev/features/f8-package-private/PLAN.md b/.dev/features/f8-package-private/PLAN.md new file mode 100644 index 0000000..d329e2d --- /dev/null +++ b/.dev/features/f8-package-private/PLAN.md @@ -0,0 +1,34 @@ +# PLAN — f8-package-private + +- spec_content_hash: 8f5ec002e3b18cbfd2f094b08a3671f7ed42a05a3fbaf01a11bbbd28da30fb52 +- applied_lessons: [L8, L19] +- increment: Add `"private": true` and remove the dead `"main": "index.js"` field from `package.json` so a real `npm publish` refuses instead of shipping the whole repo. +- layer(s): repo-meta (not a `pharn/` capability layer — `package.json` sits outside `pharn-contracts` / `pharn-core` / `pharn-pipeline` / `pharn-review`) +- constitution_refs: [P6, P7] + +## Applied lessons + +- L8 — This increment's sole output is one file (`package.json`); the writes-scope for `/pharn-dev-build` will resolve to that single `--target`, matching L8's "favor single-file command outputs" guidance directly (no multi-artifact placeholder to lose scope on). +- L19 — Any format/lint command run over this change during build or this plan's own artifact-formatting step must be scoped to the specific written file (`npx prettier --write package.json`, `npx prettier --write .dev/features/f8-package-private/PLAN.md`), never a repo-wide `npm run format`, so no unrelated file is silently swept into this increment's diff. + +## Files + +- `package.json` — add `"private": true` after `"version"`; delete the `"main": "index.js"` line — layer repo-meta + +## Contracts satisfied + +- None — `package.json` is not a `pharn-contracts` schema, a Capability, or a rule/lens/griller. This is a repo-meta correction outside the capability tree, so no `pharn-contracts` entry applies (CLAUDE.md, "Repo layout — the dev/product boundary"). + +## Evals to write (P1) + +- None — P1 ("no Capability ships without evals") governs `role:`-bearing Capabilities under `pharn/`. `package.json` carries no `role:` frontmatter and is not a Capability, so P1 does not apply to this increment. + +## Guarantee audit (P0) + +- "A real `npm publish` refuses once `private: true` is set" → **advisory (external system behavior)**. This is npm's own documented behavior, not a reduction to one of PHARN's three floor primitives (hook / content-hash / enum-regex) — no PHARN-side hook, hash, or enum check enforces it. It is stated as an observable npm behavior, never labeled a PHARN guarantee. +- "`package.json` still parses and is prettier-clean after the edit" → **floor-adjacent, enforced by the existing gate**: `npm run format:check` (part of `npm run check`) already runs `prettier --check .` over the whole repo, so a malformed or unformatted `package.json` fails that pre-existing gate. No new floor primitive is added by this increment. +- "This edit does not alter the product surface" → **enum/regex-reducible, by inspection**: `package.json` is not in CLAUDE.md's bump-triggering set (the `pharn/` capability tree, `pharn/floor/*.mjs`, the four trusted docs, the product `.claude/` surface) — it is named explicitly under "Pure repo-meta ... does not bump either." No `SKILLS_VERSION` bump, no floor check needed to prove it (the claim rests on the already-published, human-authored enumeration in CLAUDE.md, not on a new mechanism this increment invents). + +## Open questions (HALT) + +- None. The defect is reproduced live (see plan args), the fix is a two-field JSON edit with no ambiguity, and CLAUDE.md is dispositive on the no-bump question. diff --git a/.dev/features/f8-package-private/REGRESSION.md b/.dev/features/f8-package-private/REGRESSION.md new file mode 100644 index 0000000..86d5c9e --- /dev/null +++ b/.dev/features/f8-package-private/REGRESSION.md @@ -0,0 +1,39 @@ +# REGRESSION — f8-package-private + +**Base:** `HEAD` (working-tree dogfood — `git status --porcelain` was non-empty, so base = HEAD per +the deterministic auto-detect rule). + +## Partition + +- **Inside (changed scope):** `.dev/features/f8-package-private/GRILL.md`, + `.dev/features/f8-package-private/PLAN.md`, `package.json` +- **Declared (`## Files` in the approved plan):** `package.json` +- **Escaped:** none +- **Escape-exempt (this feature's own stage artifacts, per `--feature`):** + `.dev/features/f8-package-private/GRILL.md`, `.dev/features/f8-package-private/PLAN.md` +- **Style-gate skip:** applied — `inside` touches no shared style config + (`eslint.config.mjs` / `.prettierrc.json` / `.prettierignore` / `.markdownlint-cli2.jsonc`), so + `lint` / `format:check` / `lint:md` are provably unable to flip outside the feature and were skipped + at both base and head. + +## Outside gates run (base → head) + +| gate | base | head | +| ------------------------------------------------------------------------------------------ | ---- | ---- | +| `tests` (63 outside `*.test.mjs`/`*.test.cjs` files) | 0 | 0 | +| `validate` (`pharn/floor/validate.mjs .`) | 0 | 0 | +| `structural:pharn/pharn-review/trust-fence/evals/expected/expected-injection-comment.json` | 0 | 0 | + +## Regressions + +None. + +## Pre-existing failures + +None. + +**REGRESSIONS: none — no deterministically-detectable breakage outside the feature.** + +This certifies only the comparison: every gate this suite runs was green at the pre-build baseline and +stays green at HEAD. It does not certify the feature itself is correct or complete — it catches exactly +what the deterministic suite covers, nothing more (P0). diff --git a/.dev/features/f8-package-private/REVIEW.md b/.dev/features/f8-package-private/REVIEW.md new file mode 100644 index 0000000..b3df03c --- /dev/null +++ b/.dev/features/f8-package-private/REVIEW.md @@ -0,0 +1,84 @@ +# REVIEW — f8-package-private + +**Floor first (P0):** `node pharn/floor/validate.mjs .` → `FLOOR: GREEN — 36 capabilities checked in .` +(exit 0). The increment reached review on a green floor. + +**Diff under review** (`git diff HEAD -- package.json`): adds `"private": true` after `"version"`; +removes the `"main": "index.js"` line. Nothing else changed. The increment is `trust: untrusted` per +the loaded prefix; no instruction-looking content was found in the diff (it is two JSON key edits, no +comments, no strings a model could be steered by). + +## L-floor → P0 + +Re-checked the plan's guarantee audit against what actually landed: + +- "A real `npm publish` refuses once `private: true` is set" — labeled `advisory` (external npm + behavior, no PHARN floor primitive). Correct label; `private: true` is now live in `package.json`, + confirmed by direct read (`require('./package.json').private === true`). +- "`package.json` still parses and is prettier-clean" — floor-adjacent via the pre-existing + `format:check` gate, re-confirmed GREEN at `/pharn-dev-verify` (after a whitespace-only reformat of + `regression-report.json`, unrelated to this file — see `VERIFY.md`). +- "No `SKILLS_VERSION` bump" — enum/regex-reducible by inspection against CLAUDE.md's bump-triggering + set; `package.json` is explicitly named as pure repo-meta. `SKILLS_VERSION` file is untouched + (confirmed: still `2.5.1`). + +No blocking finding. No guarantee is claimed here without a floor reduction or an `advisory` label. + +## L-eval → P1 + +`package.json` carries no `role:` frontmatter and is not a Capability; P1 ("no Capability ships without +evals") does not apply. No `enforces` / `rule_id` binding is introduced. Nothing to check — no finding. + +## L-trust → P2 + +No untrusted artifact is ingested by this increment's own content. The reviewed diff contains no +free-text finding output of its own to fence. No finding. + +## L-axis → P3 + +One file changed (`package.json`), no sibling module reference, no `pharn-contracts` bypass. The two +edits (`add private` / `remove dead main`) were flagged at `/pharn-dev-grill` as a possible axis-bundling +concern (`GRILL.md`, `rule_id: P3`, severity minor) — re-examined here: both edits serve the single +stated axis ("`package.json` currently presents this repo as publishable/importable when it is +neither"), and splitting them into two PRs would produce no independent value (the `main` removal has no +meaning without the `private` context that explains why it's dead, and vice versa). Not elevated to +blocking; recorded as **advisory, minor** — same severity as the grill finding. + +## Findings + +```yaml +- type: FINDING + rule_id: P3 + severity: minor + file: "package.json:1" + problem: "Two edits (add 'private', remove dead 'main') are bundled under one plan axis; defensible but worth naming explicitly in the PR description rather than left implicit." + evidence: 'diff: +"private": true (line 4); -"main": "index.js" (line 26, pre-edit)' +``` + +**Gate:** advisory-gate (warn) — not a floor-detectable sibling reference, rests on judgment of what +counts as "one axis." Does not block. + +## Verdict + +**GREEN — 0 blocking floor-gate findings, 1 minor advisory-gate finding.** The increment is done: floor +GREEN, regress clean (`regression-report.json`: `no-regressions`), verify PASS +(`verify-report.json`: `PASS`, 0 verifiers registered), review raises no blocker. + +## Proposed lesson candidate (NOT promoted here — human-gated `/pharn-dev-memory-promote` only) + +**Candidate:** A `/pharn-dev-plan` for a non-Capability repo-meta fix can satisfy `check-plan-lessons.mjs` +and the P1 eval-coverage question ("None — not a Capability") while still omitting a plain verification +checklist — "how do we confirm the fix worked" — because no floor check requires one outside the +testability griller's advisory Layer-1 presence check. `/pharn-dev-grill`'s testability lens caught the gap +in this run (`GRILL.md`, `rule_id: P1`, severity important) on `.dev/features/f8-package-private/PLAN.md`, +which had no declared verification section despite the originating request including an explicit +checklist that never made it into the plan's structure. The gap was harmless here — `/pharn-dev-build` and +`/pharn-dev-verify` independently confirmed the fix live and via the deterministic gate set — but a plan for +a more complex non-Capability change could omit verification with no downstream stage catching it before +review. + +**Provenance:** feature `f8-package-private`; surfaced by `.dev/features/f8-package-private/GRILL.md` +(testability griller finding, this run); commit `unknown` (uncommitted at review time). + +**Not promoted:** single occurrence, not yet a recurring pattern (P7 — a real trigger exists, but +promotion is the human's call at a separate, gated `/pharn-dev-memory-promote` run). diff --git a/.dev/features/f8-package-private/SHIP.md b/.dev/features/f8-package-private/SHIP.md new file mode 100644 index 0000000..01657c6 --- /dev/null +++ b/.dev/features/f8-package-private/SHIP.md @@ -0,0 +1,44 @@ +# SHIP — f8-package-private + +Gated `/pharn-dev-ship` run over the increment "add `\"private\": true`, remove the dead `\"main\": \"index.js\"` +field from `package.json`" (F8). + +## Stages run, in order + +1. `/pharn-dev-plan` → `.dev/features/f8-package-private/PLAN.md` → **GATE 1: approved as written** (human). +2. `/pharn-dev-grill` → `.dev/features/f8-package-private/GRILL.md` → advisory, 4 concerns (0 blocking, 1 + important, 3 minor) — gates nothing, proceeded. +3. `/pharn-dev-build` → `package.json` edited (2 fields) → `pharn/floor/validate.mjs .` exit **0** + (`FLOOR: GREEN — 36 capabilities checked in .`). +4. `/pharn-dev-regress` → `.dev/features/f8-package-private/regression-report.json` / + `REGRESSION.md` → `.verdict` = **`no-regressions`**. +5. `/pharn-dev-verify` → `.dev/features/f8-package-private/verify-report.json` / `VERIFY.md` → `.verdict` = + **`PASS`** (`test`, `validate`, `lint`, `format:check`, `lint:md`, + `structural:pharn/pharn-review/trust-fence/evals/expected/expected-injection-comment.json` — all exit 0; 0 + verifiers registered). +6. `/pharn-dev-review` → `.dev/features/f8-package-private/REVIEW.md` → **GREEN**, 0 blocking floor-gate + findings, 1 minor advisory-gate finding (P3, axis-bundling — examined and not elevated); one lesson + candidate proposed (not promoted — requires a separate gated `/pharn-dev-memory-promote` run). + +**Where the run ended:** reached the end of the chain (`/pharn-dev-review` complete) — **this is GATE 2.** + +## Structural verdicts, verbatim + +| stage | verdict source | value | +| -------------------- | -------------------------------------------------------------------- | ---------------- | +| `/pharn-dev-build` | `pharn/floor/validate.mjs .` exit code | `0` (GREEN) | +| `/pharn-dev-regress` | `.dev/features/f8-package-private/regression-report.json` `.verdict` | `no-regressions` | +| `/pharn-dev-verify` | `.dev/features/f8-package-private/verify-report.json` `.verdict` | `PASS` | + +## Pointers (not restated — P4) + +- `.dev/features/f8-package-private/GRILL.md` — advisory grill-log (4 findings: P1 important, P0/P3/P2 + minor). +- `.dev/features/f8-package-private/REVIEW.md` — 4-lens review + 1 proposed (unpromoted) lesson + candidate. + +## Standing decision + +The chain ran; the named floor verdicts are as shown above. **This is NOT a judgment that the increment +is good or wise** — that is the human's call at this post-review gate (merge / fix / abandon). No +merge, push, or `PHARN ✓ reviewed` seal was applied by this run. diff --git a/.dev/features/f8-package-private/VERIFY.md b/.dev/features/f8-package-private/VERIFY.md new file mode 100644 index 0000000..cd63261 --- /dev/null +++ b/.dev/features/f8-package-private/VERIFY.md @@ -0,0 +1,32 @@ +# VERIFY — f8-package-private + +## Floor layer (deterministic — owns the verdict) + +| gate | exit | +| ------------------------------------------------------------------------------------------ | ---- | +| `test` (`npm test`) | 0 | +| `validate` (`pharn/floor/validate.mjs .`) | 0 | +| `lint` (`npm run lint`) | 0 | +| `format:check` (`npm run format:check`) | 0 | +| `lint:md` (`npm run lint:md`) | 0 | +| `structural:pharn/pharn-review/trust-fence/evals/expected/expected-injection-comment.json` | 0 | + +**VERIFIED: floor gates PASS.** + +Note: `format:check` initially failed (exit 1) on `.dev/features/f8-package-private/regression-report.json` +— `check-regress.mjs`'s raw `JSON.stringify(obj, null, 2)` output does not match Prettier's array-collapsing +style. Reformatted it with `npx prettier --write` (whitespace-only; content unchanged) before the final gate +run, matching the convention already visible in other committed `regression-report.json` files in this repo +(e.g. `.dev/features/verify-style-gates/regression-report.json`). All gates above are from the clean re-run. + +## Advisory layer (verifiers) + +No verifiers registered — floor gates only (`node pharn/floor/count-verifiers.mjs .` → `{"registered":0,"verifiers":[]}`). + +## Honest residual + +Verified = the named gates passed; this is NOT a guarantee of correctness beyond what those gates check +— verifier concerns are advisory help, not assurance. This run additionally confirms live, by direct +inspection, that `require('./package.json').private === true` and `.main === undefined` — the specific +behavior the plan set out to produce — though that confirmation is orchestration (this command's own +check), not a gate in the `gates` map above. diff --git a/.dev/features/f8-package-private/regression-report.json b/.dev/features/f8-package-private/regression-report.json new file mode 100644 index 0000000..5e3f93f --- /dev/null +++ b/.dev/features/f8-package-private/regression-report.json @@ -0,0 +1,21 @@ +{ + "base": "HEAD", + "inside": [".dev/features/f8-package-private/GRILL.md", ".dev/features/f8-package-private/PLAN.md", "package.json"], + "outside_gates": { + "structural:pharn/pharn-review/trust-fence/evals/expected/expected-injection-comment.json": { + "base": 0, + "head": 0 + }, + "tests": { + "base": 0, + "head": 0 + }, + "validate": { + "base": 0, + "head": 0 + } + }, + "regressions": [], + "pre_existing": [], + "verdict": "no-regressions" +} diff --git a/.dev/features/f8-package-private/verify-report.json b/.dev/features/f8-package-private/verify-report.json new file mode 100644 index 0000000..a1b2944 --- /dev/null +++ b/.dev/features/f8-package-private/verify-report.json @@ -0,0 +1,14 @@ +{ + "feature": "f8-package-private", + "gates": { + "format:check": 0, + "lint": 0, + "lint:md": 0, + "structural:pharn/pharn-review/trust-fence/evals/expected/expected-injection-comment.json": 0, + "test": 0, + "validate": 0 + }, + "verdict": "PASS", + "failing_gates": [], + "verifiers": { "registered": 0, "findings": [] } +} diff --git a/package.json b/package.json index 1331bae..2377f45 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "pharn-oss", "version": "1.0.0", + "private": true, "description": "Audit-grade methodology for AI-native development. Skills, commands, lenses, and rules that turn AI sessions into versioned artifacts — so your codebase stays legible past month six. Claude Code first; Codex and Cursor next.", "keywords": [ "audit", @@ -23,7 +24,6 @@ "license": "Apache-2.0", "author": "Przemysław Galarowicz", "type": "commonjs", - "main": "index.js", "scripts": { "test": "node --test \"**/*.test.mjs\" \"**/*.test.cjs\" \".claude/**/*.test.mjs\" \".claude/**/*.test.cjs\" \".dev/**/*.test.mjs\" \".dev/**/*.test.cjs\" \"pharn/**/*.test.mjs\" \"pharn/**/*.test.cjs\"", "lint": "eslint .",