Compare commits

...
Author SHA1 Message Date
Frank e030486ce6 docs: pin cwd meaning in attribution footer
Mirror of command-center clarification: first dogfooding round stamped the
build worktree instead of the session's own working directory. Rule text
now says which one, and to note the build worktree in the body.
2026-10-18 16:41:21 -07:00
Frank d89ae23195 docs: attribution footer for machine-opened issues and PRs
Mirror of dank/command-center's rule (there: PR off docs/session-trailer-rule).
Every agent-opened issue/PR body ends with cwd + omp session id so machine-filed
artifacts trace back to the box and session that produced them.

Refs #11 (command-center tracker)
2026-10-18 16:32:59 -07:00
dank f206ddfde5 Merge pull request 'Docs: codify trunk-based git workflow in AGENTS.md' (#6) from chore/trunk-based-git-workflow into main 2026-10-18 15:43:29 -07:00
Frank bf29518a15 Docs: PRs get opened in Frank's browser the moment they're filed
Fleet law alignment with dank/command-center: no PR-hunting in Gitea.
tests/run.sh ALL TESTS PASSED before commit.
2026-10-18 15:41:14 -07:00
Frank 169dbe2f38 Docs: codify trunk-based git workflow in AGENTS.md
The section mandated a source-test-push loop but never stated a branch
regime - agents pushed straight to main. Fleet alignment (operator
decision 2026-10-18, mirrors dank/command-center): main is the only
long-lived branch; branch fresh off origin/main per work item; PRs
target main with --no-ff; merge only on Frank's explicit OK; tags on
main. Their tests/run.sh suite: ALL TESTS PASSED before push.
2026-10-18 15:27:53 -07:00
Frank 4a6d5b8191 docs(log): frank-tts phase 1 landed as PR #4; PTQ1_0 provenance line finished
The dragoon-window provenance bullet still said the zealot arm owed a
measurement — it does not: the numbers are recovered and in the fetch script and
runbook. Adds the frank-tts phase-1 entry (naming law, port 7772, voice-pack law,
384/384 suite, PR #4 merged as 49c4e19, and the measured Gitea merge-field law).
2026-10-18 14:12:32 -07:00
dank 49c4e198fd Merge pull request 'feat(frank-tts): cloned-voice speech endpoint (phase 1)' (#4) from wt/20261017-181502 into main 2026-10-18 14:08:13 -07:00
2 changed files with 77 additions and 13 deletions

No files matched your search

+28 -8
View File
@@ -48,17 +48,37 @@ the [runbook index](#runbook-index). The full swap history lives in
pages (`serverAppConfigs-docs/log.md` carries the wave plan and results)
- `tests/` — bats suite + Playwright e2e
## Git Workflow
## Git Workflow — trunk-based (fleet law, aligned 2026-10-18)
All edits flow through git. Never edit files on a remote machine directly.
1. **Source** the live config from the target machine
2. **Commit** the fetched version here (redact secrets into `.env`)
3. **Edit** locally
4. **Test** — `./tests/run.sh` must pass
5. **Commit and push** — origin is Gitea on Dankclaw
6. **Pull** on the target (`deploy.sh` does this)
7. **Deploy** — `scripts/deploy.sh` plans and dispatches only changed services
`main` is the only long-lived branch: no `develop`, no release branches, no
back-merges. Frank is the only dev; this repo and `dank/command-center` follow
the same regime.
1. **Branch fresh** — `git fetch`, then branch off the current `origin/main`
(`<type>/<slug>`, type ∈ feat|fix|docs|chore). If main moves under you,
merge it into your branch — never rebase.
2. **Source** the live config from the target machine
3. **Commit** the fetched version here (redact secrets into `.env`)
4. **Edit** locally
5. **Test** — `./tests/run.sh` must pass
6. **Push the branch and open a PR against `main`** — origin is Gitea on
Dankclaw. Merge with `--no-ff`; **never merge a PR without an explicit,
current OK from Frank.** **The moment the PR is open, open it in Frank's
browser** (`xdg-open <PR-URL>` — a Firefox tab on the workstation); never
make him hunt for it in Gitea. Releases: tag `vX.Y.Z` straight on `main`.
7. **Pull** on the target (`deploy.sh` does this)
8. **Deploy** — `scripts/deploy.sh` plans and dispatches only changed services
**Attribution footer (issues and PRs)** — every issue or PR body you open MUST end with:
```
---
cwd: <working directory> · session: <omp session id>
```
Session id from `/status`; `cwd` is that session's own working directory — not the build checkout, when they differ (note the build worktree in the body instead). Machine-made artifacts stay attributable to the box and session that spawned them.
## Deployment
+49 -5
View File
@@ -2247,11 +2247,12 @@ every restart since the cutover.
the 9B swap of the same day had not reached those two spots. Re-keyed: 8
full-attention + 24 Gated DeltaNet + the `blk.32` MTP block, 3 × 262,144,
tensor type **141**.
- PTQ1_0 provenance corrected: `scripts/download-frank-zealot-bonsai2-ptq1.sh`
IS committed, so the armed-but-never-measured arm that hijacked the zealot
deploy was a **repo-tracked candidate**, not an orphan. The runbook now states
the decision it still owes: measure it in a real window, or record it
declined.
- PTQ1_0 provenance corrected (see the dedicated section above): the arm that
hijacked the zealot deploy was a **repo-tracked, Frank-ordered, measured**
candidate — `scripts/download-frank-zealot-bonsai2-ptq1.sh` is committed, and
its header now carries the recovered numbers (≈48 t/s decode, 801 t/s prefill
at 141k) and the verdict: −37 % decode against PQ2_0 for 1,201 MiB freed, then
scratched by Frank's 03:33 order in favour of the 9B. Nothing is owed on it.
- OpenWebUI: both decoration rows re-keyed in the live DB. The values live
inside JSON columns — `params.context.length` and `meta.description` — not in
fields named for them, and there is no `sqlite3` binary on the host, so
@@ -2267,3 +2268,46 @@ every restart since the cutover.
`timings` object and the `ttft;dur=` header are **llama.cpp** instruments —
frank-zealot's, not dragoon's. AGENTS.md's Benchmarking Policy re-keyed to
say which engine owns which instrument.
## 2026-10-18 — frank-tts phase 1: the cloned-voice endpoint, named and tested (not deployed)
- Voice-over goal, phase 1 (Gitea issue #2). New service **frank-tts** on
Dankclaw: `dankclaw/voiceservice/` (stdlib-only `app.py` + `Containerfile` +
rootless quadlet), `scripts/frank-tts.env`, `tests/frank_tts_unit.bats`
(12 tests). One OpenAI-shaped `POST /v1/audio/speech` surface; `voice=<name>`
is honoured only when `/voices/<name>/reference.wav` exists, otherwise a 400
listing the voices that are — no silent fallback voice. `voice_id` is the
harness alias; `response_format=mp3` really is mp3; oversized input is a 414,
not a half-narrated sentence; `/health` reports backend + voice list; no audio
ever reaches the log. Two backends behind it (`TTS_BACKEND=omni-http` forwards
to the host's `:8880` engine with the voice as base64 `reference_audio`;
`llama-tts-cli` runs a binary per request at `nice -n 19`), both exercised
through stubs — no GPU, no containers in the seam.
- **Naming law applied (Frank's call):** treat it as a first-class model
endpoint → alias-named `frank-tts` (TTS endpoint, so not `frank-asr`),
**port 7772**, joining `7770 frank-dragoon` / `7771 frank-zealot`; the engine
upstream keeps 8880 and is deliberately not a fleet endpoint. The internal
knob names stay `SHIM_*` (they name the façade component, not the service).
- **Voice-pack law recorded** in the env header: a pack needs `reference.wav`
(24 kHz mono, 18–25 s) **and** the pinned engine's own speaker artifact —
required, beside the WAV, never replacing it — plus `manifest.json` provenance
whose offsets are always past the first 10 s of the source (the
source-material law). Enforcement is split honestly: the shim gates on
`reference.wav` (the only engine-agnostic term); the pack builder is what will
refuse to emit a pack without its artifact.
- Suite green: **384/384** (`./tests/run.sh`, wall 66 s). Landed as **PR #4**
(branch `wt/20261017-181502` → `main`, merged as `49c4e19`) — the first PR on
this repo through the API, which cost three 422s to get right: the merge
endpoint takes **`{"Do":"merge"}`**, `Do` being a *string* naming the strategy.
`DoMerge`/`merge_method` do not exist on this Gitea; swagger JSON is disabled
on the instance, so the 422 messages are the schema. Law saved to the
`gitea-api-pr-operations` skill.
- Deliberately NOT in this phase: the `:8880` engine decision and its
speaker-artifact format, the pack builder, deployer/homepage/Prometheus
registration, the `models.yml` row that lets omp call it, and open-notebook.
Harness fact established while writing the PR body: the **`tts` tool** will
dispatch an `api: openai-speech` provider row to `POST <baseUrl>/audio/speech`
(`{model, input, response_format, voice}`), but the live `speech.*` vocalizer is
Kokoro-enum-only — so "the agent talks in my voice" needs that provider row or
a `pi.registerProvider` extension, decided in phase 2.