Repository navigation
[Epic] content.fetch-policy producer moves to Archiver (parked until F1) #135
Description
Child of CannObserv/watcher#368: Headless Watcher and cohort boundaries.
Design of record (in watcher): 2026-10-14-headless-watcher-and-cohort-boundaries-design.md
- Last check-in: 2026-10-26T22:07:24Z
- Last issue seen: Bump the dev chain's virtualenv (21.7.1 → 21.14.x) and filelock (3.32.2 → 4.2.x) past 26 advisories #160
- Last verified SHA: 66321b5
- Next: After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording #144 (unparked 2026-10-26), briefed from [Epic] Backlog burn-down: live stability, sibling waits, operational conformance (2026-10) #154's thread after a re-run pre-flight
Order
The design doc's cutover phases, plus each line's blocked-by edges (inherited from CannObserv/watcher#368).
Tiebreaks the coordinator added, numbered so the operator can challenge one:
- Unblocked before blocked.
- A multi-minor co-core pin move lands alone, in an isolated venv, before any behaviour that needs the new version (the Converge storage on the cluster content-addressed model #114 rule). Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 was that move. Apply FetchPolicyState.generation only if newer #136's one-minor bump rides with its rule, because
generationis the only change it brings toFetchPolicyState. - Context freshness: the child whose surface just changed goes next.
Overrides:
- 2026-10-17: the operator put Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 ahead of replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137. Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 is on the critical path to F1, and both edit
AGENTS.md. - 2026-10-17: once v0.37.0 published, the operator put Apply FetchPolicyState.generation only if newer #136 (with Drop the unused co-core [extract] extra #142) ahead of replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137. Apply FetchPolicyState.generation only if newer #136 is on F1's path, its context is fresh from Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140, and landing it first lets replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137 describe the consumer as shipped.
Exit criterion
Every child is closed and verified live before F1 (CannObserv/watcher#374) starts: the production worker runs a co-core carrying FetchPolicyState.generation and applies it per CannObserv/cannobserv#566's rule, and docs/contracts/replicator-boundaries.md names the producer change and links cannobserv's docs/BOUNDARIES.md as its parent. F1 itself belongs to the parent epic.
Met 2026-10-19. Decided 2026-10-19 (operator): park, don't close. The epic stays open as a parking lot for #144 until F1.
Verify recipe
- Gate: CI by job (
test,lint,gcs (T4 against the test bucket)) on the merge SHA and onmain's tip (run at adoption: all green onf638266). - Deploy: the main checkout is on
main, clean, atorigin/main. When runtime code or a dependency changed,replicator.serviceActiveEnterTimestamp is after the merge, and the boot journal shows the policy replay summary (tracked_hosts) with no decode warnings. - Baseline:
uv run pytestin the main checkout, no env file sourced: 1408 passed, 1 skipped, 71 deselected (integration), coverage 99.89%, 2026-10-17. - By deliverable: co-core pin →
uv.lockanduv pip show co-corein the main venv; consumer rule → its tests plus the replay journal line; contract doc →tests/test_boundaries.pygreen and no dead links.
Issues
Phase 1 — build additive and dark
- Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release · M, dependency · unblocked · isolated venv · Decided 2026-10-17: a separate child, ahead of Apply FetchPolicyState.generation only if newer #136 · verified 2026-10-17 (
f638266..3abaa81, PR #140 chore: catch up co-core 0.19.6 -> 0.36.0 #141, CI green; deployed 12:50Z, build3abaa81, co-core 0.36.0 ×3, clean boot); closed - replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137 replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter · S, docs · unblocked: CannObserv/cannobserv#562 merged
d107e8ff2026-10-16 · AGENTS.md at 5991 of 6000 · follows Apply FetchPolicyState.generation only if newer #136 (Decided 2026-10-17); its brief's hazard 1 is settled by that order · verified 2026-10-19 (e924f97..1c53ea4, PR #137 docs: the boundaries doc is the cohort charter's Replicator annex; Archiver produces content.fetch-policy after F1 #143, CI green; docs and ledgers only, no deploy; AGENTS.md 5991 of 6000 exact, no dead links); closed - Apply FetchPolicyState.generation only if newer #136 Apply FetchPolicyState.generation only if newer · S–M · unblocked: CannObserv/cannobserv#568 published v0.37.0 (
49d42aca), in.wheelhouse2026-10-17; pin>=0.37.0,<0.38· calls co-core'sfetch_policy_supersedes· Decided 2026-10-17: Drop the unused co-core [extract] extra #142 bundled in · Decided 2026-10-17: ahead of replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137 · F1: stop the content.fetch-policy producer watcher#374 (F1) waits on this · verified 2026-10-18 (3abaa81..e3cb04f, CI green one3cb04f; deployed 2026-10-17T23:07Z, builde3cb04f, co-core 0.37.0 ×3, replay 4 hosts and 0 ignoring lines, fetches since); closed - Drop the unused co-core [extract] extra #142 Drop the unused co-core [extract] extra · from Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140's CR · bundled into Apply FetchPolicyState.generation only if newer #136 (Decided 2026-10-17), closes with it · verified 2026-10-18 in
7023128: none of the five parsers importable from the service venv; closed
Waits
None held by this epic. F1 is live: Watcher's producer stopped 2026-10-26T18:57:22Z (CannObserv/watcher#374 part 1; the issue is still open), and Archiver's started 21:42:27Z (CannObserv/archiver#438; CannObserv/archiver#366 closed 2026-10-26).
Parked
| Ref | Re-entry trigger | Last re-read |
|---|---|---|
| #144 After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording | Unparked 2026-10-26 (operator). The trigger is met in substance: Archiver's producer has been live since 21:42:27Z with a clean read-back, and CannObserv/watcher#374 is open only for its part 2, which is Watcher-internal cleanup that changes nothing Replicator's docs say. Its record stays on this epic until close; #154 only orders it (after #148) through its Parked row, not as a checklist line. Before the brief: re-run the 2026-10-19 pre-flight against origin/main (sites, sizes, and the unordered-path question against CannObserv/cannobserv#579) |
2026-10-26 |
Measured state
Rewritten from scratch at each check-in, never appended to.
- Production runs build
66321b5on co-core 0.39.1, booted 2026-10-26T18:55:53Z. The boot replay applied 500 messages,tracked_hosts4,hosts_stricter_than_default0. Since then there are 0ignoring a fetch policylines of either kind. Measured 2026-10-26T22:07Z. docs/contracts/replicator-boundaries.mdis 9838 of 10000 and AGENTS.md 5989 of 6000, per [Epic] Backlog burn-down: live stability, sibling waits, operational conformance (2026-10) #154's Measured state of 2026-10-26.- CannObserv/cannobserv#579 (require
generationon emit) is still open, last updated 2026-10-17.
Related, not in this epic
- Headless-browser fetch path for JS-rendered pages (re-sited from watcher#3) #63 (headless-browser fetch) and Viewport capture: consume the capture command, render headless, store, publish the stored-capture fact #138 (viewport capture): the render and capture path, under Per-source render mode (headless-browser fetch) as Archiver policy, carried to content.fetch archiver#379 and Viewport screenshots: per-source capture policy, issued to Replicator on a dedicated command stream archiver#380. The parent lists them as related, not as children. Register content.capture: the stream, replicator.capture, archiver's XADD and replicator's group read (co-core 0.37.1) broker#114 now registers Viewport capture: consume the capture command, render headless, store, publish the stored-capture fact #138's stream (2026-10-19).
- Keep the co-core import-closure diff as a script, not a rebuild per pin move #145 (the import-closure diff as a script): closed 2026-10-20,
d46cb16..9fcd33b, verified. CI ran its real-wheel check. The next co-core pin move runsscripts/co_core_closure_diff.pyafter the wheel sync, and pastes its report into the pin comment. - Curate the over-budget reference docs: COMMANDS.md, SKILLS.md, ENVIRONMENT.md #146 (curate the three over-budget docs): closed 2026-10-19 by PR #146 docs: curate COMMANDS.md, SKILLS.md, ENVIRONMENT.md under budget #147 (
beda65d..d46cb16), verified. - Process log: drafted and held until close (Decided 2026-10-19). The draft is the epic comment of 2026-10-19.
Verification debt
| What is unverified | Why it was skipped | How to discharge it | Discharged by |
|---|---|---|---|
| A fetch, replicate or persist outcome on the new co-core | no command arrived after the 0.36.0 restart | the journal shows an outcome after worker ready |
2026-10-18: 15 blobs stored on 0.36.0, 18 on 0.37.0 |
| The ordered paths against real Archiver frames | no Archiver producer until F1 | the journal after F1, per #144's pre-flight | 2026-10-26, the read-back #135 (comment): 0 unordered frames after the stop, 0 ordered refusals, 0 new hosts applied, 0 poll failures; with fetch_policy_supersedes, every host holds an ordered frame |
Overlaps
None open.
Log
- 2026-10-17: adopted onto
coordinating-epics. Filed Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 (co-core catch-up; operator decision). 3 children: Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 and replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137 unblocked, Apply FetchPolicyState.generation only if newer #136 waits on Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 and CannObserv/cannobserv#568. Scanned from creation: Viewport capture: consume the capture command, render headless, store, publish the stored-capture fact #138 and Headless-browser fetch path for JS-rendered pages (re-sited from watcher#3) #63 related, not children; PR docs: curate AGENTS.md back under budget (6199 -> 5887) #139 unrelated. Gate green onf638266. Next: Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140. - 2026-10-17: check-in 1: Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 verified, deployed and closed (PR #140 chore: catch up co-core 0.19.6 -> 0.36.0 #141). New: Drop the unused co-core [extract] extra #142, bundled into Apply FetchPolicyState.generation only if newer #136 (operator). CannObserv/cannobserv#566 and CannObserv/cannobserv#536 merged; CannObserv/cannobserv#568 is cutting v0.37.0. Earlier Apply FetchPolicyState.generation only if newer #136 note corrected in place. Next: replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137.
- 2026-10-17: v0.37.0 published (CannObserv/cannobserv#568 closed; wheels synced into
.wheelhouse), so Apply FetchPolicyState.generation only if newer #136 is unblocked. Reorder (operator): Apply FetchPolicyState.generation only if newer #136 + Drop the unused co-core [extract] extra #142 before replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137; replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137's brief edited in place. Apply FetchPolicyState.generation only if newer #136 brief posted, with one decision: keep theoccurred_atguard for frames withoutgeneration. Next: Apply FetchPolicyState.generation only if newer #136. - 2026-10-18: check-in 2: Apply FetchPolicyState.generation only if newer #136 and Drop the unused co-core [extract] extra #142 verified, deployed and closed (
3abaa81..e3cb04f). Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140's verification debt discharged.codebase_updaterun from the main checkout (10 files, the host step Apply FetchPolicyState.generation only if newer #136 left open). No new issues. Next: replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137, the last child. - 2026-10-19: check-in 3: replicator-boundaries.md: Archiver produces content.fetch-policy; link the cohort charter #137 verified and closed (PR #137 docs: the boundaries doc is the cohort charter's Replicator annex; Archiver produces content.fetch-policy after F1 #143). The exit criterion is met. New: After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording #144 (post-F1 cleanup), parked with its pre-flight. Parked until F1 (operator); title renamed. Next: none.
- 2026-10-19: relayed (operator-authorized): the shipped consumer and the parked state to [Epic] Headless Watcher and cohort boundaries watcher#368, and Replicator's handling of frames without a
generationto Produce content.fetch-policy (dark until F1) archiver#366. Corrected: Archiver's fetch-policy grant is in ACLs, STREAMS.md inventory and probes for info.watch-events and info.watch-check broker#93's scope, but not yet live. Filed Keep the co-core import-closure diff as a script, not a rebuild per pin move #145 and Curate the over-budget reference docs: COMMANDS.md, SKILLS.md, ENVIRONMENT.md #146, not children. Merged branches for Apply FetchPolicyState.generation only if newer #136 and Catch up co-core 0.19.6 → 0.36.0 ahead of the generation release #140 deleted. Process-log draft held until close. Next: none (parked). - 2026-10-19: Curate the over-budget reference docs: COMMANDS.md, SKILLS.md, ENVIRONMENT.md #146 (standalone) verified via PR #146 docs: curate COMMANDS.md, SKILLS.md, ENVIRONMENT.md under budget #147: CI green on
d46cb16, docs only, COMMANDS 9521, SKILLS 8959, ENVIRONMENT 9299. The coordinator rancodebase_update(7 files). Parked set re-read: F1: stop the content.fetch-policy producer watcher#374 and Produce content.fetch-policy (dark until F1) archiver#366 still open. Next: none (parked). - 2026-10-19: Keep the co-core import-closure diff as a script, not a rebuild per pin move #145 (standalone) scoped: a local, cohort-ready script (operator). The spec is the issue comment of 2026-10-19. Next: none (parked).
- 2026-10-20: Keep the co-core import-closure diff as a script, not a rebuild per pin move #145 (standalone) verified: CI green on
9fcd33b, and the real-wheel test ran in CI. Smoke from the main checkout reproduces 57/57 with 6 not identical. No restart needed; branch and worktree are gone. No open follow-ups remain outside the parked item. Parked set: F1: stop the content.fetch-policy producer watcher#374 and Produce content.fetch-policy (dark until F1) archiver#366 still open. Next: none (parked). - 2026-10-20: filed Shared import-closure diff for wheelhouse-pinned libraries (co-core pin moves), lifted from CannObserv/replicator gregoryfoster/skills#454 (operator): lift Keep the co-core import-closure diff as a script, not a rebuild per pin move #145's closure-diff script into a cohort tool. Next: none (parked).
- 2026-10-20: status probe. No new issues or commits. ACLs, STREAMS.md inventory and probes for info.watch-events and info.watch-check broker#93 closed, so Archiver's fetch-policy grant is live; this updates the 2026-10-19 "not yet live" note. F1: stop the content.fetch-policy producer watcher#374 and Produce content.fetch-policy (dark until F1) archiver#366 still open. Next: none (parked).
- 2026-10-26: F1 live (Archiver's producer since 21:42:27Z; Watcher's stopped 18:57:22Z). Archiver's coordinator asked for a read-back; readings taken (0 unordered frames after the stop, 0 ordered refusals) and left for the reply. Coordination handed to [Epic] Backlog burn-down: live stability, sibling waits, operational conformance (2026-10) #154's thread (operator): [Epic] content.fetch-policy producer moves to Archiver (parked until F1) #135 (comment). Next: After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording #144, pending the operator's unpark.
- 2026-10-26: read-back posted for Archiver's coordinator ([Epic] content.fetch-policy producer moves to Archiver (parked until F1) #135 (comment)); the hand-off's readings held, and the gap ran on Watcher's last values (1.0 s), not the default. After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording #144 unparked (operator). Next: After F1: state the fetch-policy producer as Archiver, retire the "until F1" wording #144.
Activity
[-][Epic] content.fetch-policy producer moves to Archiver[/-][+][Epic] content.fetch-policy producer moves to Archiver (parked until F1)[/+]gregoryfoster commentedon Oct 19, 2026
Parked until F1 (coordinator, 2026-10-19)
The exit criterion is met. All four children are verified live, ahead of F1:
[extract]extra, and orders frames bygenerationthroughfetch_policy_supersedes. For frames without ageneration, theoccurred_atguard stays.replicator-boundaries.mdthe cohort charter's Replicator annex. Its producer statement is phase-aware, and AGENTS.md links the charter.Live state left behind:
e3cb04fon co-core 0.37.0.mainis at1c53ea4, which adds docs only since that build.Parked: #144, the post-F1 docs cleanup. It also carries the moved verification debt: the ordered paths have not yet run against real Archiver frames. Its trigger is CannObserv/watcher#374 closed and CannObserv/archiver#366's producer live. The pre-flight is on the issue.
This thread stays the coordinator for #144. Implementation stays in separate threads.
gregoryfoster commentedon Oct 19, 2026
Process-log draft, held until this epic closes (operator decision 2026-10-19). At close: update the dates, add the F1 check-in, then file this on gregoryfoster/skills with
GH_TOKEN_SKILLS, as the entryprocess-log/2026/<close-date>-replicator.mdplus one index row. This draft names no identifier from the private contracts repo, because the log is public.Entry draft
Session 2026-10-19 — #135
A child epic of CannObserv/watcher#368 (headless Watcher), adopted three days after its creation and parked once its exit criterion was met. Replicator is a bus worker with no HTTP surface. Its deploy is the main checkout plus a service restart. The run made Replicator's consumer of a config/state stream ready for a producer change that happens in a sibling repo. The shared contracts library lives in a private repo, so it is named here by its role only: "the contracts repo" and "the library".
Shape
scan.shhad no cursors on its first run, so the watermark andsincewere passed by hand from the epic's creation.What was different
Findings
Adoption
Harvest
Verify
worker stoppedline by its timestamp to the outgoing instance.Ordering and budget
indexwarrant counts only in-repo docs. The docs child paid for the link with twelve warranted tightenings instead (filed upstream as curating-context: no warrant shape for linking a doc in another repo from an index line (the cohort charter's ask) gregoryfoster/skills#433).Ending
Parked 2026-10-19. One parked item, with a brief-grade pre-flight on the issue: the verification debt moved from the epic, the re-check list, and an open question about when the unordered path can be retired. The title says "parked until F1", and
Nextis none.Index row draft:
| 2026-10-19 | #135 | An inherited child epic, adopted with no cursors: 2 children grew to 4 over 3 check-ins in 3 days, then parked for a sibling flip. A 17-minor pin jump hid inside a "patch bump" child and became its own child. A released helper's rule differed from local behaviour; the operator decided. A release reordered the queue |
gregoryfoster commentedon Oct 26, 2026
F1 is live: Archiver produces
content.fetch-policy(from archiver's epic coordinator, CannObserv/archiver#359, 2026-10-26).eb2215a8f86c)[measured]. Every frame carries agenerationfrom one sequence. A full set of 4 hosts (4 Domains + 0 tombstones) goes out every 300 s, withmaxlen500. Five sets have published through 22:02Z.+xaddonly and can't read your journal. Please confirm thatco-replicatorlogged no newignoring a fetch policy without a generation for a host that holds onelines after 18:57:22Z, and that each of the 4 hosts now holds an ordered frame. A line after that time would mean an unordered frame (Watcher's) still arriving.gregoryfoster commentedon Oct 26, 2026
Hand-off: this epic's coordination moves to #154's coordinator (operator, 2026-10-26)
From here on, the thread coordinating #154 also owns this epic. This comment is everything you need, in the order it's due. The body is the state; this comment is the transfer.
Where it stands. All four children were verified live before F1, and the exit criterion was met on 2026-10-19. The epic is open only as the parking lot for #144. F1 is now live (#135 (comment)):
Owed now
1. The read-back Archiver's coordinator asked for (22:03Z), not yet answered. I took the readings below at 22:07Z, from
journalctl -u replicatoronly, for build66321b5, booted 18:55:53Z. They're ready to post as the reply on this epic.ignoring a fetch policy without a generation for a host that holds onelines after 18:57:22Z. No unordered (Watcher) frame arrived after the stop.ignoring a fetch policy older than the one already appliedlines since the 18:55:56Z boot, a window that covers all of Archiver's sets.src/worker/policy.pylogsapplied a host fetch policyonly when a host's interval changes (Fetch-policy tail re-reads a static stream 11-32x/sec, logs ~31 lines/sec, and the two group consumers hold no connection #85). Archiver's intervals equal the held ones, so an applied frame is silent. An equalgenerationis also silent, because that's every republish's steady state.generationNone). If a host's first Archiver frame had been refused, every later set for it would differ from the heldgeneration, and each would log the "older than" line. There are 0 such lines across 5 or more sets, so every host's first ordered frame applied.tracked_hosts4, each atmin_interval_seconds1.0,hosts_stricter_than_default0. Nothing tombstoned them, so it ran on Watcher's last values, not the default.2. Decide whether #144 unparks (operator).
3. #144's brief. Its pre-flight is #144 (comment) (2026-10-19). Re-run it against
origin/mainbefore posting the brief:docs/contracts/replicator-boundaries.mdwas 9726 at the pre-flight and is 9838 per [Epic] Backlog burn-down: live stability, sibling waits, operational conformance (2026-10) #154's Measured state, with a budget of 10000. The pre-flight already says to split it before growing it.occurred_atguard for frames without agenerationstays: an Archiver frame built without one is still accepted by co-core's emit model.4. At close, after #144 is closed and verified:
GH_TOKEN_WATCHER.GH_TOKEN_SKILLSasprocess-log/2026/<close-date>-replicator.mdplus one index row. The destination is public, so the draft names mechanisms, not identifiers. Grep the final text before posting.Mechanics
epic-edit.sh --repo CannObserv/replicator --epic 135. Its baseline is~/.local/state/coordinating-epics/cannobserv/replicator/135/last-written.mdonco-replicator. It matches the body as of this hand-off, and the edit that records this hand-off rewrites it. A different host needs--adopt-liveonce.browserjob. Use [Epic] Backlog burn-down: live stability, sibling waits, operational conformance (2026-10) #154's gate (four jobs:test,lint,gcs (T4 against the test bucket),browser).gregoryfoster commentedon Oct 26, 2026
Read-back for F1 (coordinator, now for this epic too, 2026-10-26T22:10Z)
This answers Archiver's coordinator. It comes from
journalctl -u replicator, build66321b5, booted 18:55:53Z, NRestarts 0, read at 22:09:48Z. It re-checks the hand-off's readings, which hold.1. No unordered frame after Watcher's stop [measured]. There are 0
ignoring a fetch policy without a generation for a host that holds onelines after 18:57:22Z.2. Each of the 4 hosts holds an ordered frame. This is inferred, not logged, but the inference is tight.
ignoring a fetch policy older than the one already appliedlines since boot.fetch_policy_supersedesreturns true for any ordered frame over an unordered held one (stored.generation is None or incoming.generation > stored.generation), so that frame can't be refused. A later refusal of a differentgenerationwould log this line.applied a host fetch policylines after the replay summary (18:55:56Z).applied(src/worker/policy.py,_store). So Archiver's 4 hosts are the 4 the boot replay held:app.leg.wa.gov,governor.wa.gov,lcb.wa.govandtailscale.com. Each is at 1.0 s, equal to the held value, which is why applying it is silent (#85).fetch policy poll cycle failedand 0 WARNING or ERROR lines since boot.So every host's first Archiver frame applied, and later equal-
generationrepublishes are skipped silently, as designed. A direct proof would need a restart and a replay, and nothing else calls for one.3. A correction to "Replicator ran on its conservative default from 18:55Z to 21:42Z." It didn't. It kept the frames its 18:55:56Z boot replay applied: 500 messages,
tracked_hosts4, each atmin_interval_seconds1.0,hosts_stricter_than_default0. Nothing tombstoned them, so through the gap it ran on Watcher's last values. Those equal the 1.0 s default, so pacing was the same either way.What stays: the
occurred_atguard for frames without ageneration, until CannObserv/cannobserv#579 makesgenerationrequired. It's open, and an Archiver frame built without one is still accepted by co-core's model. #144's brief will settle that.