Skip to content

fix(pkg): mark pharn-oss private, drop the dead main entry point - #135

Merged
PrzemekGalarowicz merged 1 commit into
mainfrom
fix/f8-package-private
Aug 12, 2026
Merged

fix(pkg): mark pharn-oss private, drop the dead main entry point#135
PrzemekGalarowicz merged 1 commit into
mainfrom
fix/f8-package-private

Conversation

@PrzemekGalarowicz

@PrzemekGalarowicz PrzemekGalarowicz commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add "private": true to package.json so a real npm publish refuses instead of pushing this methodology repo (.dev/, pharn/, .claude/) under the publishable name pharn-oss — the distributable package is @pharn-dev/pharn, not this repo.
  • Remove the dead "main": "index.js" field (file never existed), so the package no longer claims an import surface it does not have.
  • Both edits are one axis: package.json currently claims a publish/import surface this repo does not have. No SKILLS_VERSION bump — pure repo-meta.

Test plan

  • Confirm require('./package.json').private === true and .main === undefined
  • Confirm npm publish --dry-run refuses (or would refuse) with a private-package error
  • CI green: npm test, pharn/floor/validate.mjs ., lint/format gates
  • Review audit trail under .dev/features/f8-package-private/ (verify PASS, regress no-regressions, review GREEN)

Made with Cursor

Summary by CodeRabbit

  • New Configuration

    • Marked the package as private to prevent unintended publication.
    • Removed the obsolete package entry point declaration.
  • Documentation

    • Added verification, review, regression, and release records documenting the configuration change and validation results.
  • Validation

    • Confirmed all applicable checks passed with no detected regressions or blocking issues.

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 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The package is now private and no longer declares index.js as its main entry point. F8 planning, verification, regression, review, grill, and ship records document the change and its validation results.

Changes

Package privacy metadata

Layer / File(s) Summary
Package metadata plan
.dev/features/f8-package-private/PLAN.md
The plan defines the private: true change, removal of main, scope, and validation requirements.
Package metadata update
package.json
The package is marked private, and the main entry is removed.
F8 validation and delivery records
.dev/features/f8-package-private/{VERIFY.md,verify-report.json,REGRESSION.md,regression-report.json,GRILL.md,REVIEW.md,SHIP.md}
The added records document gate results, regression status, grill findings, review status, and ship-gate outcomes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes both package metadata changes: marking the repository private and removing the obsolete main entry point.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/f8-package-private

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: dependency version conflict. Check your lock file or package.json.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.dev/features/f8-package-private/GRILL.md:
- Around line 17-40: Update the P1, P0, and P3 findings in
.dev/features/f8-package-private/GRILL.md#L17-L40 to use exact line anchors for
the corresponding evidence ranges in PLAN.md rather than unrelated lines. In
.dev/features/f8-package-private/REVIEW.md#L49-L55, replace package.json:1 with
the exact changed package.json ranges. Preserve each finding’s existing scope
and content while making all references actionable.

In @.dev/features/f8-package-private/PLAN.md:
- Around line 22-34: Expand .dev/features/f8-package-private/PLAN.md with a
verification section documenting acceptance checks for package fields, npm
publish --dry-run, CI, and feature-audit validation, including each command,
expected result, and scope. Keep npm’s refusal of publishing private packages
explicitly advisory, and retain the existing P1 and P0 audit conclusions.
- Around line 26-30: The “This edit does not alter the product surface”
conclusion in the Guarantee audit is incorrectly labeled enum/regex-reducible;
change it to advisory wording because the package exclusion is not enforced by a
floor checker. In PLAN.md, add the package-specific verification checklist
requested by the comment, while preserving the existing CLAUDE.md enumeration
reference and no-bump conclusion.

In @.dev/features/f8-package-private/verify-report.json:
- Around line 3-13: The package-field acceptance check is missing from the
verification report. In .dev/features/f8-package-private/verify-report.json, add
a structured check matching the VERIFY.md requirement that private === true and
main === undefined, including its command, status, and result; do not add an npm
publish --dry-run check. The corresponding requirement in
.dev/features/f8-package-private/VERIFY.md requires no direct change.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b9356d8f-f412-49c9-8b27-3baff4bf50ef

📥 Commits

Reviewing files that changed from the base of the PR and between 1fe34a9 and 0be9e77.

📒 Files selected for processing (9)
  • .dev/features/f8-package-private/GRILL.md
  • .dev/features/f8-package-private/PLAN.md
  • .dev/features/f8-package-private/REGRESSION.md
  • .dev/features/f8-package-private/REVIEW.md
  • .dev/features/f8-package-private/SHIP.md
  • .dev/features/f8-package-private/VERIFY.md
  • .dev/features/f8-package-private/regression-report.json
  • .dev/features/f8-package-private/verify-report.json
  • package.json

Comment on lines +17 to +40
- 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'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Use exact line anchors in every review artifact.

Both reports point findings at unrelated lines, which makes the recorded issues non-actionable.

  • .dev/features/f8-package-private/GRILL.md#L17-L40: update P1, P0, and P3 to the exact PLAN.md evidence ranges.
  • .dev/features/f8-package-private/REVIEW.md#L49-L55: replace package.json:1 with the changed package.json ranges.
📍 Affects 2 files
  • .dev/features/f8-package-private/GRILL.md#L17-L40 (this comment)
  • .dev/features/f8-package-private/REVIEW.md#L49-L55
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.dev/features/f8-package-private/GRILL.md around lines 17 - 40, Update the
P1, P0, and P3 findings in .dev/features/f8-package-private/GRILL.md#L17-L40 to
use exact line anchors for the corresponding evidence ranges in PLAN.md rather
than unrelated lines. In .dev/features/f8-package-private/REVIEW.md#L49-L55,
replace package.json:1 with the exact changed package.json ranges. Preserve each
finding’s existing scope and content while making all references actionable.

Comment on lines +22 to +34
## 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the acceptance checks to the plan.

## Evals to write (P1) only explains why Capability evals do not apply. It does not record the acceptance checks listed in the PR objectives: package-field checks, npm publish --dry-run, CI checks, and feature-audit validation. Add the commands, expected results, and scope in a verification section. Keep external npm behavior advisory.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.dev/features/f8-package-private/PLAN.md around lines 22 - 34, Expand
.dev/features/f8-package-private/PLAN.md with a verification section documenting
acceptance checks for package fields, npm publish --dry-run, CI, and
feature-audit validation, including each command, expected result, and scope.
Keep npm’s refusal of publishing private packages explicitly advisory, and
retain the existing P1 and P0 audit conclusions.

Comment on lines +26 to +30
## 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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- PLAN ---'
sed -n '1,90p' .dev/features/f8-package-private/PLAN.md
printf '%s\n' '--- CLAUDE bump rules ---'
rg -n -A12 -B8 'bump|trigger|Pure repo-meta|SKILLS_VERSION|package\.json' CLAUDE.md
printf '%s\n' '--- floor files ---'
git ls-files 'pharn/floor/*.mjs'

Repository: pharn-dev/pharn-oss

Length of output: 18719


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- bump-related enforcement ---'
rg -n -i -A5 -B5 'SKILLS_VERSION|bump-triggering|product surface|package\.json' .dev pharn .claude package.json CLAUDE.md \
  | head -n 240
printf '%s\n' '--- plan lines ---'
nl -ba .dev/features/f8-package-private/PLAN.md | sed -n '22,34p'
printf '%s\n' '--- package metadata ---'
cat package.json
printf '%s\n' '--- relevant scripts ---'
node - <<'JS'
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
console.log(JSON.stringify(p.scripts ?? {}, null, 2));
JS

Repository: pharn-dev/pharn-oss

Length of output: 25452


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- feature files ---'
git ls-files '.dev/features/f8-package-private/*'
printf '%s\n' '--- feature objectives and verification references ---'
rg -n -i -A4 -B4 'objective|verification|verify|publish|private|bump|checklist' .dev/features/f8-package-private
printf '%s\n' '--- deterministic wording and checker references ---'
python3 - <<'PY'
from pathlib import Path
import re

plan = Path(".dev/features/f8-package-private/PLAN.md").read_text()
claude = Path("CLAUDE.md").read_text()
floor = "\n".join(
    p.read_text()
    for p in Path("pharn/floor").glob("*.mjs")
    if not p.name.endswith(".test.mjs")
)

print("plan says enum/regex-reducible:",
      bool(re.search(r"enum/regex-reducible", plan)))
print("plan says no floor primitive:",
      bool(re.search(r"no floor check needed|no .*floor primitive", plan, re.I)))
print("CLAUDE explicitly excludes package.json:",
      bool(re.search(r"package\.json\s*/?\s*`?\s*/?\s*SKILLS_VERSION itself", claude)))
print("product-set sentence includes package.json:",
      bool(re.search(r"package\.json", claude[claude.find("The bump-triggering set"):claude.find("The bump-triggering set") + 800])))
print("product floor contains SKILLS_VERSION bump logic:",
      bool(re.search(r"SKILLS_VERSION|bump-triggering|package\.json", floor, re.I)))
PY

Repository: pharn-dev/pharn-oss

Length of output: 30680


Mark the no-bump conclusion as advisory.

CLAUDE.md explicitly excludes package.json from the bump-triggering set, but no floor checker enforces that set. A manual comparison is not an enum/regex check. Replace enum/regex-reducible, by inspection with advisory wording and add the package-specific verification checklist to PLAN.md.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.dev/features/f8-package-private/PLAN.md around lines 26 - 30, The “This
edit does not alter the product surface” conclusion in the Guarantee audit is
incorrectly labeled enum/regex-reducible; change it to advisory wording because
the package exclusion is not enforced by a floor checker. In PLAN.md, add the
package-specific verification checklist requested by the comment, while
preserving the existing CLAUDE.md enumeration reference and no-bump conclusion.

Source: Coding guidelines

Comment on lines +3 to +13
"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": [] }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- verify-report.json ---'
cat -n .dev/features/f8-package-private/verify-report.json
printf '%s\n' '--- VERIFY.md ---'
cat -n .dev/features/f8-package-private/VERIFY.md
printf '%s\n' '--- feature files and references ---'
rg -n -C 3 'npm publish|dry-run|private|main|verify-report|gates|verifier|acceptance|package-field' .dev/features/f8-package-private package.json pharn/floor 2>/dev/null || true

Repository: pharn-dev/pharn-oss

Length of output: 50378


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- feature directory ---'
git ls-files .dev/features/f8-package-private
printf '%s\n' '--- package metadata ---'
node - <<'JS'
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
console.log(JSON.stringify({private: p.private, main: p.main}, null, 2));
JS
printf '%s\n' '--- relevant floor/checker definitions ---'
rg -n -C 4 'count-verifiers|verify-report|failing_gates|registered|dry-run|private.*true|main.*undefined' pharn .dev package.json 2>/dev/null || true

Repository: pharn-dev/pharn-oss

Length of output: 50378


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- PLAN acceptance and contracts ---'
sed -n '14,36p' .dev/features/f8-package-private/PLAN.md
printf '%s\n' '--- REVIEW evidence ---'
sed -n '12,36p' .dev/features/f8-package-private/REVIEW.md
printf '%s\n' '--- package scripts and publish-related artifacts ---'
node - <<'JS'
const fs = require('fs');
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
console.log(JSON.stringify(p.scripts || {}, null, 2));
JS
rg -n -C 2 'npm publish|dry-run|private === true|main === undefined|package\.json.*private|package-field' .dev/features/f8-package-private .claude pharn --glob '!**/node_modules/**' --glob '!**/test*.mjs' 2>/dev/null || true

Repository: pharn-dev/pharn-oss

Length of output: 12387


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import json
from pathlib import Path

report = json.loads(Path('.dev/features/f8-package-private/verify-report.json').read_text())
verify = Path('.dev/features/f8-package-private/VERIFY.md').read_text()
plan = Path('.dev/features/f8-package-private/PLAN.md').read_text()

print('report_keys:', sorted(report))
print('gate_names:', sorted(report['gates']))
print('has_named_feature_checks:', any(k in report for k in ('checks', 'acceptance_checks', 'feature_checks')))
print('verify_has_private_check:', "private === true" in verify)
print('verify_has_main_check:', "main === undefined" in verify)
print('verify_has_publish_dry_run:', "npm publish --dry-run" in verify)
print('plan_has_publish_dry_run:', "npm publish --dry-run" in plan)
print('plan_has_private_check:', 'private' in plan and 'true' in plan)
print('plan_has_main_check:', 'main' in plan and 'undefined' in plan)
PY

Repository: pharn-dev/pharn-oss

Length of output: 605


Add the package-field check to verify-report.json.

VERIFY.md records private === true and main === undefined. verify-report.json contains no corresponding named check. Add a structured entry with the command, status, and result. Do not add an npm publish --dry-run requirement because the plan does not define it as an acceptance check.

📍 Affects 2 files
  • .dev/features/f8-package-private/verify-report.json#L3-L13 (this comment)
  • .dev/features/f8-package-private/VERIFY.md#L22-L32
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.dev/features/f8-package-private/verify-report.json around lines 3 - 13, The
package-field acceptance check is missing from the verification report. In
.dev/features/f8-package-private/verify-report.json, add a structured check
matching the VERIFY.md requirement that private === true and main === undefined,
including its command, status, and result; do not add an npm publish --dry-run
check. The corresponding requirement in
.dev/features/f8-package-private/VERIFY.md requires no direct change.

@PrzemekGalarowicz
PrzemekGalarowicz merged commit c880413 into main Aug 12, 2026
8 checks passed
@PrzemekGalarowicz
PrzemekGalarowicz deleted the fix/f8-package-private branch August 12, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant