config: clear three of 472's five QA blockers (V-459)

morning_routines, feeds, crawl.on_demand and netscan.enabled in
deploy/mavend.json; -ambient-token on mavweb, interpolated from a gitignored
/.env. All verified on the box: the dispatcher builds the morning plan,
/api/ambient answers 401/201, the crawler reads a named page, netscan finds 3
devices, and /events fills with scan:lan and ambient:notif.

Filed 482 (ambient reads a notification's wall clock as UTC). Corrected 479:
both capabilities work once configured, so it is not a routing defect.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NJYcaBiuny9UGSpFweQVQ1
This commit is contained in:
2026-08-02 15:52:56 +04:00
parent a3ec746a01
commit bec7362b7b
4 changed files with 98 additions and 2 deletions
+3
View File
@@ -40,6 +40,9 @@ deploy/telegram.env
deploy/zenmoney.token
# IMAP password, read by mavmaild (never in argv, never committed)
deploy/imap.password
# Compose interpolation secrets — MAVEN_AMBIENT_TOKEN today. docker compose
# reads this file itself; it is not an env_file on any service.
/.env
# Temp files
/tmp/
+51 -1
View File
@@ -76,6 +76,56 @@
"snippet_runes": 1500
},
"//morning_routines": [
"The daily checklist (Vikunja #280). Each item is done when its fact_key",
"gets a non-voided fact inside the window, so 'выпил воды' closes water and",
"nothing has to be ticked by hand. nudge_at fires once, at the end of the",
"window, and only for what is still open. Weekdays empty = every day."
],
"morning_routines": [
{
"name": "утро",
"window_start": "08:00",
"window_end": "11:00",
"nudge_at": "10:30",
"severity": 1,
"items": [
{ "key": "medicine", "fact_key": "medicine", "label": "лекарство" },
{ "key": "water", "fact_key": "water", "label": "вода" },
{ "key": "pets", "fact_key": "pets", "label": "покормить кота" }
]
}
],
"//feeds": [
"RSS reading (Vikunja #258). Every item lands as a note with source",
"rss:<name>, which is also what puts entries in the intake journal that",
"/events reads. Only the feed URL leaves the box.",
"This is a starting pair, not a curated set — trim or extend it."
],
"feeds": {
"poll_interval": "30m",
"max_items": 5,
"max_age": "24h",
"sources": [
{ "name": "lwn", "url": "https://lwn.net/headlines/newrss", "category": "технологии" },
{ "name": "archlinux", "url": "https://archlinux.org/feeds/news/", "category": "технологии" }
]
},
"//crawl": [
"Reading a web page (Vikunja #259). on_demand answers 'посмотри <URL>'.",
"No allow_hosts, so any public host he names is readable; private",
"addresses are refused unconditionally by internal/webfetch and do not",
"need listing. Setting allow_hosts here would also narrow on-demand,",
"which is the point of leaving it empty."
],
"crawl": {
"on_demand": true,
"timeout": "10s",
"max_runes": 4000
},
"digest": {
"enabled": true,
"window": "30m",
@@ -119,7 +169,7 @@
"timeout": "400ms",
"rate": 100,
"max_hosts": 256,
"enabled": false
"enabled": true
},
"nexus": { "url": "http://nexus:9740" },
+9
View File
@@ -79,7 +79,16 @@ services:
<<: *image
# voice.bind is 0.0.0.0:9100 in deploy/mavend.json so mavweb can reach it
# cross-container. Verified 2026-07-06.
# -ambient-token turns on POST /api/ambient (Vikunja #126): the phone posts
# notification text, mavweb keeps only a meeting time. Empty ⇒ no route at
# all, which is what a missing MAVEN_AMBIENT_TOKEN gives. The value comes
# from the gitignored .env docker compose reads for interpolation, NOT from
# an env_file — flags are interpolated before any service env exists.
# Weakness worth naming: mavweb takes this as a flag, so it is visible in
# `ps` inside this container, unlike the zenmoney and IMAP secrets which are
# read from files.
command: ["mavweb", "-addr", ":9201", "-voice", "mavend:9100", "-core", "/run/maven/mavend.sock",
"-ambient-token", "${MAVEN_AMBIENT_TOKEN:-}",
"-nexus", "http://nexus:9740", "-praxis", "http://praxis:8989", "-hexis", "http://hexis:9741"]
depends_on: [mavend]
# loopback-only on purpose: /tools defines+executes arbitrary argv and
+35 -1
View File
@@ -46,10 +46,15 @@ Sessions 1, 2 and 3 all ran. Read these five before picking anything up.
with a general article about network hardware. A question about his LAN went to
an upstream engine. The crawler fails the same way.
Twenty defects were filed on 02-08-2026: 462 through 481. Six tasks this plan
Twenty-one defects were filed on 02-08-2026: 462 through 482. Six tasks this plan
had written off as blocked turned out to be ready to check. All six ran. Every
one of them is code-correct and stops at the deploy.
Three of the five config blockers in **472** were then cleared. The morning
routine, ambient ingest, feeds, the crawler and netscan are all live. Two remain,
and both are the owner's call: a token for each ecosystem sibling, and seed data
in Nexus and Praxis.
---
## Before you start
@@ -256,6 +261,27 @@ its presence rule passes on inspection. Three of its five items need traffic the
box has not had. **283 is blocked**: nothing feeds the intake journal. **128
found the worst defect of the whole session, see below.**
Three of 472's five blockers were cleared the same day, in `deploy/mavend.json`
and `docker-compose.yml`.
- A `morning_routines` block, one routine `утро` 08:00-11:00 with medicine,
water and pets. It is live: the dispatcher logged `dropped morning:утро (sev1,
presence=away)`, so the plan builds and the nudge is proposed. 280's
behaviours and 128 step 11 are checkable now. 473 still stands.
- `-ambient-token` on mavweb, value in a gitignored `/.env` that docker compose
reads for interpolation. `/api/ambient` answers 401 without the token and 201
with it, storing `calendar_event_20260802_Standup`. 283 step 5 and 128 step 8
are unblocked. The token is a flag, so it shows in `ps` inside that container.
The zenmoney and IMAP secrets are read from files instead. Ingest also
reads the notification's wall clock as UTC and stores a 14:30 meeting at 18:30
(**482**).
- `feeds` (two sources), `crawl.on_demand` and `netscan.enabled`. The intake
journal now fills: `/events` holds `scan:lan` and `ambient:notif` rows.
Two are not mine to clear. No sibling has a `token` in `deploy/mavend.json`, so
273 steps 6 and 8 need a credential decision. Nexus has no entities and Praxis no
attention items, so 272 step 3 needs seed data whose content is the owner's call.
For **285**, two facts bear on the choice. Synapse is already running on this box
and healthy, so a Matrix reach has a live target and needs no new service. And
mavweb is already a PWA with a service worker, which 285 itself calls the highest
@@ -451,6 +477,14 @@ need the block enabled. Step 10 is Bluetooth and stays skipped.
**259, crawler.** Steps 1 and 15 pass. Step 2 fails. Steps 3 to 14 need a `crawl`
block that nobody has written.
Both were configured later the same day, and both work. `netscan.enabled: true`
answers `какие устройства в сети?` with `нашла 3 устройства, из них 2 с вебом, 2 с
ssh. список записала.` and the scan lands in the intake journal as `scan:lan`.
`crawl.on_demand: true` answers `посмотри https://lwn.net — что там пишут?` from
the real page. So **479** is one defect, not the routing defect it was filed as.
An unconfigured capability declines its own turn instead of naming the gap.
Nothing is wrong with the routing.
257 step 1 and 259 step 2 fail the same way and share a task (**479**). An
unconfigured capability does not name the gap, so the question escapes to web
search. `какие устройства в сети?` was answered with a general article about