These are the product’s technical docs at this revision. Historical version names and status notes are preserved; see Releases for download qualifications.
Read as MarkdownHubnot
On this page
- Hubnot
- Project status
- Download and install
- Build and verify
- Portable projects and independent audits
- Start a repository
- Issues that grow with the work
- Projects, discussions and workflows
- Familiar local commands and optional transfers
- Distinct device actors
- Inspect and amend policy
- Select and synchronize facts
- Record and recall agent memory
- Proposals, CI, decisions, and merge
- Command surface
- Opt-in check protection and automerge
- Completed alpha boundary
- Documentation
- License
Hubnot is an experiment in distributing collaboration with a Git repository.
Git distributes the work; Hubnot distributes the signed intent, discussion,
policy, and evidence around it. There is no Hubnot service or database: an
ordinary Git remote transports both code and refs/hn/* collaboration facts.
The active command and protocol namespace is hn. This is a deliberate
pre-user hard reset: there is no nh executable, alias, fallback reader,
migration, or actor-continuity bridge. This repository's tracked configuration
lives in .hn/. The obsolete .nh/ directory is ignored; its earlier contents
remain in Git history. Legacy .git/nh/** and refs/nh/* state is also ignored.
Hubnot creates fresh identities and facts only in the active namespace.
The current operational alpha supports signed issues, planning projects and items, threaded discussions, versioned native workflows, immutable proposal candidates and revisions, reviews, CI requests/results/logs, governance decisions and merge facts, distinct device actors, policy amendments, selected quarantined replication, exact shallow-history recovery, deliberate signed agent memory, portable project migrations and independent observational audits. It remains an experimental protocol, not a stable or hardened multi-tenant system.
Project status
The initial operational-alpha roadmap is complete. Hubnot has used its own
published protocol to revise, independently sandbox-test, approve, accept, and
merge changes into public main. An ordinary Git remote carried the code and
signed collaboration refs; it did not supply Hubnot-specific governance or
CI services.
"Alpha complete" means the end-to-end protocol boundary documented here is implemented and exercised. It does not mean production-ready: compatibility is not yet stable, the security boundary is intentionally narrow, and the deferred work in Completed alpha boundary is the post-alpha roadmap.
Download and install
Hubnot 0.0.2-dev is the current portable-collaboration alpha prerelease. Prebuilt executables require Git 2.x on your PATH. Running them requires no Python, Go, Docker, or forge account.
Mac runtime testing is still pending for 0.0.2-dev. Both macOS architectures have been cross-compiled and inspected. Both Linux architectures passed runtime smoke checks in standard and native-only variants.
Mac testing has since identified a migration limitation in these published packages: issue #16 requires physical explicit paths and a physical TMPDIR in the CLI environment for the tested round trip. Source corrections and the permanent regression gates are documented in filesystem portability; these published binaries remain unchanged.
| Platform | CPU | Standard | Native only |
|---|---|---|---|
| Linux | Intel / AMD 64-bit | Download | Download |
| Linux | ARM64 | Download | Download |
| macOS | Intel | Download | Download |
| macOS | Apple Silicon | Download | Download |
Standard builds include the optional GitHub, GitLab, Forgejo/Codeberg, Gitea,
Bitbucket Cloud and Azure DevOps adapters. Native-only builds omit every network
provider adapter and retain native collaboration, local/archive migration,
independent audits and local hn gh issue commands. Both variants install as
hn; choose one. Protected checks, automerge and audits remain independently
disabled by default.
Download SHA256SUMS
alongside your archive and verify it before extraction. On Linux, use
sha256sum --ignore-missing -c SHA256SUMS. On macOS, use
shasum -a 256 <archive.tar.gz> and compare the matching checksum entry.
The source archive
and build provenance
are also available.
Extract your archive, enter its directory, then install:
mkdir -p "$HOME/.local/bin"
install -m 0755 hn "$HOME/.local/bin/hn"
export PATH="$HOME/.local/bin:$PATH"
hn version
Keep that PATH setting in your shell configuration if needed. The archives also contain the MIT license, build provenance, and product documentation. See the changelog for release history and platform qualification.
All eleven release assets reproduced byte-for-byte with Go 1.26.4, and published downloads match the verified local bundle. Linux AMD64 and ARM64 runtime smoke checks covered signed native issues, saved archive migration, exact imported actor history and local continuation. Mac runtime testing remains pending for both Intel and Apple Silicon; testing of the previous release does not qualify these new binaries. macOS downloads have no Apple Developer ID signature or notarization, so a quarantined download may require approval in Privacy & Security. The release notes include the detailed platform evidence and distribution limits.
Build and verify
Building from source requires Go 1.26 or newer and Git 2.x. Docker and Python are not required for the following build and test commands.
go build -trimpath -o hn .
go test -count=1 ./...
# Omit GitHub only, or every network adapter. Native commands remain available.
go build -trimpath -tags nogithub -o hn-local .
go build -trimpath -tags noforge -o hn-native .
Packaging 0.0.2-dev uses Go and Git alone, with no Python requirement. The
published archives were built with Go 1.26.4 from commit
e80880abc792e2c386182e06027fc251b134c0d2. Build the Go-only packager and
select that exact revision to reproduce them:
go build -trimpath -o hn-release ./cmd/hn-release
./hn-release --rev e80880abc792e2c386182e06027fc251b134c0d2 --version 0.0.2-dev --out NEW_DIRECTORY
The output directory must not exist. Optional --source DIRECTORY,
--targets linux/amd64,linux/arm64,darwin/amd64,darwin/arm64 and
--variants standard,native-only select declared inputs. The packager isolates
the exact committed source, disables automatic VCS stamping, uses no shell or
module network, and writes normalized binary/source archives, BUILD.json,
PROVENANCE.json and SHA256SUMS. It never tags or publishes. Current
native-only packages exclude all network adapters with nogithub,noforge;
the published first release's native-only assets excluded GitHub only.
The packager cross-compiles for macOS and Windows; execution on those packager
hosts remains unverified for this delivery. CLI target cross-compilation also
requires separate runtime evidence, as qualified above. The immutable first
release's build-release.py still requires Python 3.12+, Git and Go 1.26.4 to
reproduce its historical archives; its tags and assets stay unchanged.
Windows CLI distribution remains outside the current target set.
The end-to-end acceptance scenarios compile the CLI and exercise the self-hosted governance/CI loop, repository-native agent memory, and rich issues through real Git repositories:
go test -count=1 -run 'TestOperational(SelfHostingAlpha|AgentMemory)$' ./...
go test -count=1 -run '^TestOperationalRichIssue' -v ./...
Run the full local release checks with:
go test -race -timeout 20m ./...
go vet ./...
git diff --check
Bubblewrap is used by the default Linux CI executor when you choose to execute
a pipeline. It is not required for identity, policy, proposal, review,
replication, inspection, or verification commands. The explicit unsafe host
executor remains available for controlled debugging. macOS has no bundled safe
CI execution backend; host execution requires the existing explicit
--allow-unsafe-host-execution opt-in.
Portable projects and independent audits
Guided and scripted migration uses one saved
plan/apply/resume engine for local repositories, archives and explicitly selected
providers. Inspect capabilities, source bytes and loss/mapping findings before
writing; apply requires --confirm-apply or the exact guided answer APPLY.
A timeout or negative lookup never authorizes repeating an uncertain create.
Snapshots retain selected Git history, exact signed
native facts and retrieved attributed foreign records/blobs. Import preserves
destination governance and private identity state; source history grants no
native roles. Offline inspection and local continuation work with noforge.
The provider guide distinguishes tested
profiles, native mappings, raw source preservation and unavailable recreation.
Existing explicit hn transfer behavior remains available.
Independent audits require optional committed audit roles,
a separately adopted private authority anchor, owner-authorized rules, an
explicit request and a separate execute command. For example, after declaring
the roles and committing .hn/pipelines/check.json:
hn audit authority set --ref refs/heads/main --expect absent
hn audit rule authorize check --source pipeline --at HEAD
hn audit request --at CODE_REV --rule check --operation inspect-release
hn audit execute FULL_REQUEST --backend sandbox
hn audit show FULL_RESULT
hn audit follow-up FULL_RESULT --operation triage-release
Reads need no signing key. Audits can inspect old or already merged code without
a proposal. Passing and failing audit results neither block nor qualify proposal
CI, reviews, acceptance or merge. Execution preserves the sandbox default;
--backend host requires --allow-unsafe-host-execution on every invocation.
Follow-ups are explicit linked native issues, deduplicated across retries and
later results without overwriting operator edits. Concurrent independent
publishers remain visible; there is no distributed exactly-once guarantee.
Imports, requests, initialization, upgrades and merges start no audit worker.
Protected checks, automerge and audits are independent opt-ins, all disabled
unless explicitly configured. No scheduler, service or provider account is
required.
Start a repository
hn init --name "Alice's device"
hn identity public
hn issue open --body "The description" "An issue title"
hn sync origin
hn init creates a local Ed25519 identity below .git/hn/. Private keys and
local replication selections are never Git objects and are not cloned. Public
events are exact-byte signed and stored in one append-only Git history per
actor:
refs/hn/actors/<full-actor-fingerprint>
Issues that grow with the work
Start with a title and add structured descriptions, criteria, labels, assignees, relationships and namespaced metadata when useful. Edits, close and reopen append signed revisions under the same opening identity. Concurrent heads remain visible until explicitly resolved; assignment and status grant no execution or review authority.
hn issue list
hn issue show <issue-id>
hn issue heads <issue-id> --json
hn issue help
Rich issue guidance covers full-state JSON input, expected-head guards, actor-scoped operation retries, bounded pages and conflict recovery. The runnable consumer creates, reads, revises and retries demonstration work using only the public CLI. No Beads migration or consumer-specific runtime integration is performed.
Projects, discussions and workflows
Native resources are signed Git facts and remain usable with no provider:
hn project help
hn discussion help
hn workflow help
Projects contain typed planning fields and independently
revisioned items pinned to an exact schema. Discussions
keep independent replies and accepted answers pinned to exact reply content.
Workflows store native hn.pipeline/0 definitions and
inert foreign source documents. Materializing or requesting a workflow does not
execute it; the existing explicit policy/proposal/runner path governs execution.
These new native kinds require a current reader; older alpha executables may
reject them without changing their signed bytes.
Familiar local commands and optional transfers
hn gh issue implements a documented local subset using the same native issues:
hn gh issue create -t "Improve setup" -b "Document the first successful run"
hn gh issue list --state all --json id,title,state,conflict
hn gh issue view <native-issue-id> --comments
It never invokes gh, contacts GitHub or reads forge credentials. Native IDs
remain authoritative. Optional explicit transfer is separate:
hn transfer capabilities --provider github
hn transfer import --provider github --project OWNER/REPO --key 42 --dry-run
hn transfer import --provider github --resource discussion --project OWNER/REPO \
--key 7 --map history=snapshot --dry-run
The interoperability guide covers the exact
compatibility flags/JSON, all four resource mappings, credentials, bounded
preflight and uncertain-write recovery. GitHub is an optional first adapter;
there is no mandatory account, service, SDK, or unmodified-gh API bridge.
Imported facts remain usable after transport removal. Foreign workflows and
Projects automation rules are not assumed equivalent to native execution.
Distinct device actors
Initialize another clone independently, then exchange only the output of
hn identity public. The existing actor authorizes the new public key and the
new actor accepts that exact authorization:
hn identity authorize --relationship device \
--actor <full-new-actor> \
--public-key <new-public-key>
hn sync origin
# In the independently initialized target clone, after selected sync:
hn identity accept <full-authorization-event-id>
hn sync origin
hn identity list
The relationship is descriptive. It does not add the new actor to any policy
role. hn identity rotate performs the same two-sided protocol locally with a
successor relationship and retryable transaction state; it is planned
rotation while the predecessor key is available, not lost-key recovery.
Inspect and amend policy
Project governance lives in .hn/policy.json. Inspection prints complete
trust-bearing actor IDs. An amendment is an ordinary candidate, and only the
exact policy bytes from its signed base govern it:
hn policy show main
hn policy check --base main --file .hn/policy.json
hn policy check --base main --head HEAD
hn proposal open --base main --head HEAD \
--body "The base policy governs this amendment." \
"Amend collaboration policy"
Continuity relationships and replication selections never grant maintainer, reviewer, runner, or decision authority. Only the explicit full actor lists in the candidate's base policy do.
Select and synchronize facts
Save exact full actor/candidate selections and positive local budgets before synchronizing an unfamiliar remote:
hn replication select origin \
--actor <full-maintainer-actor> \
--actor <full-reviewer-actor> \
--proposal <full-candidate-event-id> \
--max-events 10000 \
--max-objects 100000 \
--max-object-bytes 16777216 \
--max-attachment-bytes 1048576 \
--max-total-bytes 268435456
hn replication show origin
hn sync origin
Each selected ref is fetched into a separate bare quarantine repository,
measured and verified, then promoted to refs/hn/remotes/<remote>/* in one
atomic ref transaction. Independently valid selections may promote when
another selected history fails. Standard Git can download a selected pack
before Hubnot measures it, so these are hard validation, promotion, and
retention limits—not portable pre-download network quotas.
A trust-sensitive command in a depth-limited clone reports a full missing ID and exact recovery action. Recovery is explicit and uses the saved selection:
hn sync origin --recover-shallow
This never performs a global unshallow and never silently adds a selector.
Record and recall agent memory
Hubnot can carry deliberate project cognition without a hosted memory
service. hn-memory/0 is separate from the collaboration protocol: each actor
owns append-only memory streams under refs/hn/memory/*, while private keys,
replication selections, and the rebuildable lexical index stay below
.git/hn/ and are never cloned.
hn memory record --kind decision --at HEAD --applies descendants \
--topic architecture --evidence git:$(git rev-parse HEAD) \
--content "Keep memory streams independent from actor event chains."
hn memory handoff --at HEAD --applies descendants --input handoff.json --json
hn memory supersede sha256:<full-memory-id> \
--kind decision --at HEAD --applies descendants \
--content "Replacement decision with current rationale."
hn replication select origin --memory sha256:<full-stream-id>
hn sync origin
hn memory index rebuild
hn memory recall --at HEAD --topic architecture --json
Default recall is policy-qualified, active, local-only, and bounded to 20 records and 65,536 encoded content bytes. Every item retains its full IDs, anchor, lifecycle edges, evidence, applicability, signature, trust class, and content digest. Memory content and handoff next actions are untrusted inert data—not instructions, truth, policy authority, or permission to act.
Add sorted memory.trustedActors and memory.trustedKinds to the exact commit's
.hn/policy.json to qualify default recall. Without it, valid signed memory is
explicitly inspectable but not trusted by default. Retraction preserves an
auditable fact; neither retraction nor deleting the private index erases
replicated Git objects.
Proposals, CI, decisions, and merge
hn proposal open --base main --head feature \
--body "Please review this exact change." "Add the feature"
hn run request <full-candidate-event-id> test
hn sync origin
# In a selected participant clone:
hn run execute <full-run-request-event-id>
hn review <full-candidate-event-id> --approve \
--body "The fetched candidate is correct."
hn sync origin
# In a maintainer clone:
hn proposal status <full-candidate-event-id>
hn decide <full-candidate-event-id> --accept
hn merge <full-candidate-event-id>
hn sync origin # publish collaboration refs
git push origin main:main # publish the primary branch separately
If Git merged the exact proposal head but recording proposal.merged failed,
retry hn merge <full-candidate-event-id>. The repair path does not merge
again: it reloads the current policy and evidence, requires one unique
first-parent merge commit that directly names the proposal head, and appends
only the missing signed fact.
Pipeline definitions are repository JSON files. A step can invoke an installed tool or an executable tracked in the candidate, without a shell unless the command itself is a shell:
{
"version": "hn.pipeline/0",
"steps": [
{
"name": "Tests",
"command": "./.hn/actions/test",
"args": ["--all"],
"timeoutSeconds": 300
}
]
}
On Linux, the default executor uses Bubblewrap with separate user, PID,
network, IPC, UTS, and cgroup namespaces; dropped capabilities; no host home;
read-only system tools; and a writable generated checkout. It exposes no
external network interface. The Bubblewrap executable and sandbox PATH are
resolved from the same fixed canonical system directories, never the invoking
shell's ambient PATH. The unsafe host backend requires both flags on every
invocation:
hn run execute <full-run-request-event-id> \
--backend host \
--allow-unsafe-host-execution
If Git reports a merge conflict, resolve it outside Hubnot and publish a new immutable revision. The predecessor and all prior evidence remain unchanged; the revision needs its own exact review, CI, and acceptance evidence:
hn proposal revise <full-predecessor-candidate-id> \
--base <full-resolved-base-commit> \
--head <full-resolved-head-commit> \
--body "Resolve the merge conflict"
hn sync origin
A runner refuses to publish a second result for the same exact request unless
the operator deliberately passes --rerun; the replacement is another signed
fact from that runner rather than a mutation of earlier bytes.
Command surface
hn init [--name NAME]
hn identity show|list|public|authorize|accept|rotate
hn issue open|revise|resolve|close|reopen|comment|list|show|heads|history|graph|operation
hn gh issue create|list|view|edit|comment|close|reopen
hn project help
hn project-item help
hn discussion help
hn discussion-reply help
hn workflow help
hn transfer import|export|capabilities --provider PROVIDER
hn github import|export --repo OWNER/REPO
hn proposal open|revise|list|show|status
hn policy show [REV]
hn policy check --base REV <--head REV|--file PATH>
hn review PROPOSAL <--approve|--request-changes> [--body TEXT]
hn run request|list|show|logs
hn run execute REQUEST [--backend sandbox|host] [--allow-unsafe-host-execution] [--rerun]
hn runner once|watch --accept-pipeline NAME --accept-actor ACTOR
hn decide PROPOSAL <--accept|--reject> [--body TEXT]
hn merge PROPOSAL
hn automerge PROPOSAL --rule NAME [--execute]
hn memory record|handoff|supersede|retract|challenge|show|recall|index
hn replication select|show [REMOTE] [--memory STREAM]...
hn sync [REMOTE] [--recover-shallow]
hn log
Trust-bearing commands require full actor fingerprints and full
sha256:<64-hex> event IDs. Short IDs are display conveniences only.
Opt-in check protection and automerge
Both capabilities are disabled unless a repository explicitly configures them in
.hn/policy.json. Initialization, upgrades and imports do not turn either on.
| Capability | Default | Explicit opt-in |
|---|---|---|
| Protected checks | Disabled | Require designated review for changes to selected check files |
| Automerge | Disabled | Permit a named rule to merge an already-accepted candidate |
| Background operation | None | Run the command yourself or through your own scheduler |
Protection and automerge are independent: either may be enabled alone. They use
native actor identities, signed evidence and ordinary Git; neither requires
GitHub, gh, a service, or a provider account.
hn automerge <full-candidate-event-id> --rule docs-only
hn automerge <full-candidate-event-id> --rule docs-only --execute
The first command previews without a signing key or mutation. The second requires
an explicitly permitted maintainer identity and current reviews, CI passes and
acceptances. It merges locally; hn sync and git push remain separate actions.
Automerge requires a full repository without active partial/promisor configuration,
a clean target equal to the candidate's signed base, and no unfinished Git operation.
Policy amendments and protected-check changes use the manual merge path.
See optional policy rules for configuration, protected baselines, execution boundaries and recovery.
Completed alpha boundary
The operational-alpha column is implemented. The deferred column describes the post-alpha roadmap; those capabilities are not implied by alpha completion.
| Area | Operational alpha | Explicitly deferred |
|---|---|---|
| Policy | Show, validate, diff, and govern amendments from exact base bytes; opt-in protected checks and explicit native automerge | Background merge queues and implicit role migration |
| Identity | Distinct actors, mutual device/successor facts, local keyring, retryable planned rotation | Lost-key, compromise, social/organizational recovery, or concurrent writers sharing one actor key |
| Replication | Exact selections, quarantine, positive budgets, validation, atomic accepted refs, compatibility-all | Portable hard pre-download quotas, moderation, selective deletion, and global redaction |
| CI | Repository-defined actions, default Bubblewrap runner, explicit unsafe host fallback | Secrets, configurable network access, strong CPU/memory/disk/process quotas, and portable/container backends |
| Memory | Signed streams, exact anchors/evidence, lifecycle projection, bounded lexical recall, disposable local index, and selected transport | Automatic capture, embeddings, semantic truth, autonomous action, federation, moderation, redaction, retention enforcement, and erasure guarantees |
| Product | CLI and Git-native signed facts | Notifications, general search, web UI, discovery, and a stable protocol compatibility promise |
Published immutable facts may be superseded by new facts, but the alpha cannot promise global erasure from every replica.
Documentation
- Changelog and next-release requirements
- Rich issues
- Projects and typed items
- Discussions and pinned answers
- Native workflows and explicit execution
- Optional forge interoperability and local gh subset
- Protocol and storage
- Agent Memory Protocol and operator guide
- Agent memory safety model
- Identity continuity and keyring safety
- Governance and policy amendments
- Selected replication and shallow recovery
- CI and runner threat model
- Hosted Git compatibility
- Operational self-hosting proof
License
Hubnot is licensed under the MIT License.