Skip to main content

Project-agnostic Goal B operating layer: bind sub-goals to goals via executable anchors, machine-checked.

Project description

pharnoss

A project-agnostic Goal B operating layer. pharnoss (pharos, the lighthouse, + harness) lets many contributors share one goal and contribute building blocks without the global plan, with alignment machine-checked instead of argued in a PR.

It pairs with any contract-first / executable-test gate. A team's goal stays the lighthouse; each iteration goal is written as an executable, self-checkable anchor bound to a real requirement; pharnoss enforces that binding deterministically.

pharnoss carries nothing project-specific: everything that binds it to a project lives in a per-project pharnoss.toml + an adapter doc. Drop it into any repo, point it at that repo's goal graph, and the gate runs.

Install

pharnoss is pure-stdlib (Python 3.11+, no third-party dependencies — just tomllib), so you can install it straight from GitHub with no package index. Pin a tag or commit (not a branch) so you control when you upgrade.

# Run ephemerally, npx-style (no permanent install):
uvx --from git+https://github.com/IanYHChu/pharnoss@v0.2.0 pharnoss init

# Or install as a re-runnable user tool:
pipx install git+https://github.com/IanYHChu/pharnoss.git@v0.2.0

# Or into the current environment:
pip install "git+https://github.com/IanYHChu/pharnoss.git@v0.2.0"

Local / editable for development: pip install -e /path/to/pharnoss. You can also run it without installing anything — see "No-install" below.

Quickstart

The Claude-Code-native path — install the skill once, then bind each project from inside Claude Code:

pharnoss install                # put the /pharnoss skill at ~/.claude (available everywhere)
# then, in Claude Code, inside any project:
/pharnoss init                  # interactively scan, confirm layout, write the binding

Or scaffold a project directly from the shell:

cd your-project
pharnoss init                   # scaffold: pharnoss.toml, the skill, a starter adapter,
                                # empty anchors/claims, a GOALS.md stub
pharnoss init --example         # ...or a runnable sample (one goal + differential anchor)
pharnoss init --auto            # headless: scan + pre-fill [repos] and goal source, no prompts
# edit pharnoss.toml ([goal].source + id_pattern) and .pharnoss/adapter.md
pharnoss check                  # the alignment gate: exit 0 aligned / 1 misaligned / 2 setup
pharnoss check --report         # human view of goal -> anchor -> claim
pharnoss run                    # the reference runner: anchors as pending/frozen tests

pharnoss install puts the project-agnostic /pharnoss skill at the user level (~/.claude/skills/pharnoss/SKILL.md, or --local for one project) so /pharnoss init exists before any project is bound. pharnoss init is the one-command bind into a project: idempotent (skips existing files; --force to overwrite), and it also drops the skill into .claude/skills/pharnoss/SKILL.md for that project.

Multi-repo projects

pharnoss binds at the umbrella / control root, once — not per repo. Declare the repos in [repos] (name = "path"; ../name when the repos sit beside a control folder) and give each anchor a target_repo from that set. With [repos] present the gate hard-fails any anchor whose target_repo is not a declared repo. pharnoss scan discovers the layout and repos, and /pharnoss init (or pharnoss init --auto) fills [repos] in for you.

CLI

Command Does
pharnoss install [--global|--local] [--force] install the /pharnoss skill (user-level by default) so it is available before any project is bound
pharnoss check [--config P] [--report] run the alignment gate (orphan / claim / manifest / repo-binding integrity hard; coverage advisory)
pharnoss run [--config P] [--report] run anchors via the reference runner (pending/frozen lifecycle; exit 0/1/2)
pharnoss init [--path D] [--force] [--example [ECO]] [--auto] scaffold pharnoss into a project (--example adds a runnable sample; --auto scans + fills [repos])
pharnoss scan [--path D] [--json] discover project layout + sub-repos (drives interactive /pharnoss init)
pharnoss update [--config P] [--json] re-sync scaffolded files to the installed pharnoss version (see Updating)
pharnoss stamp [--config P] record the current scaffolded state as the update baseline
python -m pharnoss … same, without the console script

No-install: the repo also ships check_alignment.py, a stdlib shim, so a consumer can run the gate with zero install: python3 /path/to/pharnoss/check_alignment.py (handy for CI or a consumer repo that doesn't want pharnoss as a dependency).

Updating

pharnoss has two layers, updated separately:

  1. The engine (this package — the gate, the runner, the CLI). The package manager owns it; pin a newer tag:

    pipx upgrade pharnoss                                            # if installed via pipx
    pip install --force-reinstall "git+https://github.com/IanYHChu/pharnoss.git@v0.3.0"
    
  2. The scaffolded files that live inside your repo — chiefly the /pharnoss skill. These go stale when the engine moves on. pharnoss update re-syncs them without clobbering your work:

    pharnoss update          # in your project, after upgrading the engine
    

    It records a base in .pharnoss/install.json (the pharnoss version that last scaffolded the project + a hash per tracked file) so it can tell a pristine file (safe to overwrite) from one you edited. Pristine skill files are overwritten to the latest; a file you customized is reported as needs_merge and left untouched; new optional pharnoss.toml keys are reported, never force-written. Your goal graph, anchors, claims, and adapter prose are never overwritten.

    Because pharnoss is a Claude Code extension, the merge of customized files is LLM-assisted: run /pharnoss update in Claude Code and the skill reads the report plus the maintainer-authored upgrade notes for the version span and merges new capability into your files additively, showing you a diff before finalizing.

For maintainers: any release that changes a scaffolded file (the skill, the config schema, or the adapter template) ships an upgrade note under pharnoss/upgrades/<version>.md. Keep config changes additive and backward-compatible (new keys optional with a default, no renames) so an update introduces capability rather than forcing a migration.

What pharnoss owns vs what your project owns

pharnoss owns the project-agnostic core: the manifest + claim schemas, the alignment gate (pharnoss/align.py), the /pharnoss skill (pharnoss/skill/SKILL.md), and the lifecycle (pendingfrozen = promote; the ratchet; informant-vs-judge). The default status vocabulary is pending/frozen (override via [anchors].statuses).

Your project owns the binding (pharnoss.toml): the goal graph and its id format ([goal]), the anchor manifest, the executable runner ([runner] — pharnoss ships a replaceable reference runner, pharnoss run, or point it at your own: pytest, make, cargo, …), and the adapter doc ([adapter].doc) with the project-specific HOW. See pharnoss.example.toml for the full schema.

The alignment gate

check binds three artifacts named in pharnoss.toml: the goal graph ([goal].source), the anchor manifest ([anchors].manifest, each anchor names a parent goal id), and the claim ledger ([claims].file). It finds pharnoss.toml in the current directory or any parent unless --config is given. ORPHAN anchor (parent not a real goal) and CLAIM integrity hard-fail (exit 1); goal COVERAGE is advisory — a goal with no anchor is a backfill worklist, not a failure.

The runner

check proves anchors bind to real goals; the runner proves each anchor is executable. pharnoss does not force a runner, but ships a reference one: pharnoss run reads each anchor's status and runs its check command (cmd, else [runner].anchor_cmd with {name} substituted), applying:

status check fails check passes
pending expected → green READY TO PROMOTE → red (freeze it)
frozen REGRESSION → red ok → green

Exit 0 green / 1 red / 2 setup. Promotion = flip status pending→frozen (one field; the test does not move). A project with its own contract harness points [runner] at it and ignores pharnoss run. pharnoss init --example scaffolds a working end-to-end sample (one goal, one differential anchor, a tiny impl) where both check and run are green.

Status

Standalone, installable from GitHub, with a CLI and project scaffolding. Dogfooded on a real Rust project and a non-Rust toy project (markdown goals / Python runner). Next: publish to an index; a richer init (detect the project's runner); per-project skill-install via pharnoss init.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pharnoss-0.2.0.tar.gz (34.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pharnoss-0.2.0-py3-none-any.whl (36.1 kB view details)

Uploaded Python 3

File details

Details for the file pharnoss-0.2.0.tar.gz.

File metadata

  • Download URL: pharnoss-0.2.0.tar.gz
  • Upload date:
  • Size: 34.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pharnoss-0.2.0.tar.gz
Algorithm Hash digest
SHA256 046200d6d03ea49ec7104a027d6c5b2b842b8e56dc3600cc521a16c44a43556d
MD5 0b1ba2a56cdd64cc4474402f41ac7002
BLAKE2b-256 ddf5aa69807c502790ce3c33e20de9912ff0f6d7165171af5759f3f8e8935e5f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pharnoss-0.2.0.tar.gz:

Publisher: release.yml on IanYHChu/pharnoss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pharnoss-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pharnoss-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 36.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pharnoss-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7bbfa7cbdf5b9444c8de972ab8473f103491227a1e5ea6711886611160f14aa5
MD5 c8284311510658c2f587d409520ebaaa
BLAKE2b-256 0d8a4bdab3246ef8f3183f79d66f508da89d32d9a7d8c21ffb8a5f770a3c033b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pharnoss-0.2.0-py3-none-any.whl:

Publisher: release.yml on IanYHChu/pharnoss

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page