commit - 5420dda02627f052ebf902f19bf168af2e27547b
commit + 7ae9fd34087e74f14a7cb1d230cf495ab6819245
blob - b6724082c80a911256d6058e796d6d9fd292ef01
blob + 63d2a1eb87372b59bb89ec8baa9333bcb31a0012
--- README
+++ README
built from the specification in handoff/, not from the prior C
source.
+Repository
+----------
+
+The canonical repository is:
+
+ ssh://got.fugu.farm/fugu_agent.git
+
+The OpenBSD development checkout is normally `/home/isaac/fugu2`.
+Clone it with an explicit destination when creating that checkout:
+
+ git clone ssh://got.fugu.farm/fugu_agent.git /home/isaac/fugu2
+
+The current port version is 0.2. The `v0.1` tag preserves the previous
+canonical release state.
+
Building
--------
creates that registered group automatically; a non-root staging install
may override `BINOWN` and `BINGRP` together with `DESTDIR`.
+For ordinary local deployment and package-level testing, build and install
+through the OpenBSD ports framework rather than running the source-tree
+install target as root. The complete checkout-to-package procedure,
+including the local/remote repository topology, SSH agent forwarding,
+deployment verification, rollback, and repeat installations during
+development, is in
+[docs/openbsd-development.md](docs/openbsd-development.md).
+
Layout
------
blob - /dev/null
blob + 5c2f163d2af2e47e7e50709a15cf7176c7ff298d (mode 644)
--- /dev/null
+++ docs/openbsd-development.md
+# OpenBSD development and local package installation
+
+This is the canonical procedure for building and installing fugu from the
+OpenBSD checkout at `/home/isaac/fugu2`. It keeps source verification separate
+from package verification: `make check` is the hermetic source gate, while the
+ports framework creates and installs the package that exercises `_fugu`, file
+ownership, modes, manuals, and the sample configuration.
+
+The canonical repository is `ssh://got.fugu.farm/fugu_agent.git`. The current
+port version is 0.2.
+
+## Repository and deployment topology
+
+There are three distinct locations in the normal workflow:
+
+- `/home/isaac/org/tech/coding/fugu2` is the authoring checkout on the local
+ workstation;
+- `ssh://got.fugu.farm/fugu_agent.git` is the canonical Git repository and the
+ exchange point between hosts;
+- `/home/isaac/fugu2` is a separate checkout on the OpenBSD host reached through
+ the SSH alias `server`; that host builds and installs the package.
+
+The two working directories are independent Git clones. A commit in the
+authoring checkout is not present on the OpenBSD host until it is pushed to
+`got.fugu.farm` and fetched there. Copying or synchronizing either working tree
+directly to the other host is not part of the deployment procedure. The normal
+direction is:
+
+```text
+authoring checkout
+ -> push origin/main to got.fugu.farm
+ -> fetch and fast-forward main on server
+ -> make check
+ -> build an OpenBSD package
+ -> install or reinstall the package
+ -> verify the installed program
+```
+
+`main` is the deployment branch. Deploy only committed, pushed source from a
+clean authoring checkout. The port's `V` (and `REVISION`, when present) defines
+package identity; a Git tag does not override the port metadata. Host-local
+configuration and credentials under `/etc` never travel through Git.
+
+## Push, connect, and update
+
+From the authoring checkout, review the exact commit that will be deployed and
+push it to the canonical repository:
+
+```sh
+cd /home/isaac/org/tech/coding/fugu2
+git status --short --branch
+git branch --show-current
+git push origin main
+git rev-parse HEAD
+```
+
+`git status --short` must show no changes and the branch must be `main`. Record
+the printed commit id in the deployment log.
+
+The key authorized by `got.fugu.farm` is normally held by the local SSH agent.
+Forward it when connecting to the OpenBSD build host:
+
+```sh
+ssh -A server
+```
+
+For persistent forwarding, put this on the client in `~/.ssh/config`:
+
+```sshconfig
+Host server
+ ForwardAgent yes
+```
+
+Forwarding is active only for the lifetime of the SSH connection. Confirm it
+and update the server checkout without creating a merge commit:
+
+```sh
+ssh-add -l
+cd /home/isaac/fugu2
+git fetch --prune origin
+git status --short --branch
+git switch main
+git merge --ff-only origin/main
+git rev-parse HEAD
+```
+
+The server status must be clean before the merge, and its resulting commit must
+equal the id recorded in the authoring checkout. Stop if it is dirty or cannot
+fast-forward; preserve and reconcile the server work instead of resetting it.
+`git fetch` succeeding is the useful end-to-end authentication check. The
+expected remote in both clones is:
+
+```sh
+git remote get-url origin
+# ssh://got.fugu.farm/fugu_agent.git
+```
+
+## Run the source gate
+
+On OpenBSD, use BSD make:
+
+```sh
+cd /home/isaac/fugu2
+make check
+```
+
+`make check` removes prior objects, creates object directories, rebuilds the
+entire program, and runs every regression suite. Use this shorter sequence
+only when a full clean gate is unnecessary:
+
+```sh
+make obj
+make
+make regress
+```
+
+## Create a local distfile and port
+
+Package a clean committed tree. `git archive` deliberately excludes `.git`,
+untracked files, build objects, and uncommitted changes.
+
+```sh
+cd /home/isaac/fugu2
+git status --short
+
+V=0.2
+git archive --format=tar.gz --prefix="fugu-${V}/" \
+ -o "/tmp/fugu-${V}.tar.gz" HEAD
+doas install -m 0644 "/tmp/fugu-${V}.tar.gz" \
+ "/usr/ports/distfiles/fugu-${V}.tar.gz"
+```
+
+`git status --short` must print nothing before continuing.
+
+Stage the port under `mystuff`, the location recommended for testing local or
+uncommitted ports. `mystuff` is an alternate ports root, so retain the normal
+`<category>/<port>` structure beneath it; this keeps the package path
+`productivity/fugu`. This copy is disposable; the maintained source remains
+in `port/productivity/fugu/` in the repository.
+
+```sh
+cd /home/isaac/fugu2
+ME=$(id -un)
+GROUP=$(id -gn)
+PORT=/usr/ports/mystuff/productivity/fugu
+
+doas install -d -o "$ME" -g "$GROUP" "${PORT%/fugu}"
+rm -rf "$PORT"
+cp -R port/productivity/fugu "$PORT"
+
+cd "$PORT"
+make makesum
+make package
+```
+
+`make makesum` creates the deliberately untracked `distinfo` from the exact
+archive. `make package` performs the fetch/checksum, clean extraction, build,
+fake installation, packing-list, and package creation stages. Do not copy
+files directly into `/usr/local`; the package is the artifact under test.
+
+## Deploy the package on the server
+
+All commands from distfile creation through installation run on `server` from
+its `/home/isaac/fugu2` checkout. Install a newly built package through the
+ports framework:
+
+```sh
+cd /usr/ports/mystuff/productivity/fugu
+doas make install
+```
+
+For another build of the same unpublished version, clear this local port's
+work directory, package artifact, and registered test plist, then rebuild and
+force a package-level reinstall:
+
+```sh
+cd /usr/ports/mystuff/productivity/fugu
+make clean=all
+make package
+doas make reinstall
+```
+
+`make clean=all` includes `clean=plist`. That is appropriate only while
+iterating on this disposable local port. The persistent plist repository is
+a release guard: if package contents change while the package name remains
+the same, the framework reports `Error: change in plist`. For a published
+package change, preserve the guard and bump `V` or add/increment `REVISION`
+instead.
+
+The canonical direct `pkg_add` equivalent for an unsigned locally built
+package uses a trusted package directory, not a `file:` URL:
+
+```sh
+doas env TRUSTED_PKG_PATH=/usr/ports/packages/%a/all/ pkg_add fugu-0.2
+```
+
+Normally prefer `make install` or `make reinstall`; the ports framework supplies
+the correct local package path and invokes `pkg_add` for you. A failed
+`make package` leaves no installable package, even if its intended pathname was
+printed before the failure.
+
+Verify the package registration and installed front binary:
+
+```sh
+pkg_info -e 'fugu-*'
+ls -l /usr/local/bin/fugu
+```
+
+To run fugu, create the real configuration from the installed sample, edit in
+the provider, model, and key-file path, and protect both configuration and key
+files from other users:
+
+```sh
+doas cp /etc/fugu.conf.sample /etc/fugu.conf
+doas chown root:_fugu /etc/fugu.conf
+doas chmod 0640 /etc/fugu.conf
+doas vi /etc/fugu.conf
+
+# Apply the same owner, group, and mode to every configured key file.
+doas chown root:_fugu /etc/fugu.key
+doas chmod 0640 /etc/fugu.key
+fugu -n
+```
+
+`fugu -n` parses the effective configuration and prints a redacted summary
+without contacting a provider. Then run `fugu` from the project directory.
+See `fugu.conf(5)` for every configuration option.
+
+Complete the deployment record with the source/package identities and smoke
+checks:
+
+```sh
+cd /home/isaac/fugu2
+git rev-parse HEAD
+git rev-parse origin/main
+pkg_info -e 'fugu-*'
+ls -l /usr/local/bin/fugu /usr/local/libexec/fugu
+fugu -n
+```
+
+Both commit ids must match the commit pushed from the authoring checkout.
+`pkg_info` must report the intended package version, and `fugu -n` must report
+the intended provider and model with credentials redacted.
+
+## Roll back
+
+Treat rollback as another forward deployment. In the authoring checkout,
+revert the faulty commit, bump `V` or `REVISION` when the package contents change
+under the same upstream version, commit the result, and push it to `main`. Then
+repeat the fetch, clean source gate, package build, reinstall, and verification
+steps above.
+
+Do not rewrite shared `main`, hard-reset the server checkout, install files
+directly over `/usr/local`, or restore credentials from Git. Package-managed
+sample configuration preserves the host's real `/etc/fugu.conf`; inspect that
+configuration separately if the rollback changes accepted directives or
+defaults.
+
+Remove the test package from its port directory with:
+
+```sh
+cd /usr/ports/mystuff/productivity/fugu
+doas make uninstall
+```
+
+`pkg_info` and `fugu -n` are non-destructive. `make uninstall` intentionally
+removes the installed package but preserves configuration files managed as
+samples.
+
+## Release-only checks
+
+The above is the normal local loop. Before publishing a release, also follow
+[`release-live-checks.md`](release-live-checks.md); those checks use real
+credentials and a disposable clean host and therefore are not part of
+`make check`.
+
+The workflow follows the OpenBSD
+[Porting Guide](https://www.openbsd.org/faq/ports/guide.html),
+[Working with Ports](https://www.openbsd.org/faq/ports/ports.html), and
+[Testing Guide](https://www.openbsd.org/faq/ports/testing.html). Details of
+the persistent packing-list guard and clean targets are in
+[`bsd.port.mk(5)`](https://man.openbsd.org/bsd.port.mk.5).