Repository navigation
Open
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/lLarge: multi-day or open-ended; expect staged check-insLarge: multi-day or open-ended; expect staged check-inskind/featureNew feature or capability requestNew feature or capability requestpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/queue-workerFiled or worked by the queue/worker pilotFiled or worked by the queue/worker pilot
Description
Finding
ServerConfig is fully built and parsed — and nothing in production ever loads it. The config half of #798 landed in PR #1801 (merged 39e8410, 2026-10-29): a [policy] table with freshness_window_seconds + pull_policy, [budgets], typed accessors, and startup-failing parse errors. Since then the remainder of #798 (consumption by id serve / sync sessions) has stayed blocked, and a fresh check at main 3b8d3215d808 (2026-11-03T20:15Z, task 2657 resume) shows why: there is still no production consumption point to wire the config into. This issue is that missing integration work, split out of #798 so the block has a name.
Evidence (fresh, main 3b8d3215d808)
ServerConfig::load(pkgs/id/src/server_config/mod.rs:178) has no caller outsideserver_config's own tests (parse.rs). Code search forserver_config::hits onlyserver_config/{mod,parse,provision}.rsand a doc mention inpull_policy.rs.id serve(pkgs/id/src/commands/serve.rs, 3038 lines) has no server-config flag and never referencesserver_config; itsresolve_configis the unrelated CLI bootstrap/topic defaults.- The only production
PullGateconstruction isevent_sync::open_gate()— hard-codedPullPolicy::Openover aNoWorldsmembership stub — called atserve.rs:1256for the node's own event-store sync.event_sync.rsdocuments why: "there is no world whose membership this store belongs to." EveryPullPolicy::Membersgate in the tree is in tests (log_sync.rs,event_store/sync.rs,pull_policy.rs).pull_policy.rs:22-23still states it plainly: "id servedoes not read it yet, and no session builds a gate from config." - The freshness consumer does not exist in production either:
seitan::admit(the only caller of theFreshnesswindow) is referenced only byseitan's own tests and a design spike underdoc/.Freshnessis constructed in production nowhere outsideserver_config::freshness()itself, which nothing calls. Provisioned::apply(startup provisioning from the same config) likewise has no production caller — the whole file is dead at runtime, not just the[policy]table.
Scope
id servelearns to load a server config (path flag in the existing CLI style; absent = today's behaviour, code defaults everywhere) and fails startup on a parse error, matchingServerConfig::parse's contract.- Serve builds its sync pull gate(s) from
config.pull_policy(); where a gate's store has no world membership (theevent_syncown-store case), the design must say whatmembersmeans there — refuse-all, refuse-startup-with-a-clear-error, or a membership source — and not silently serve open. - The invite-admission path that consumes
config.freshness()is wired where seitan admission is actually served, or that consumer is built as part of this work. - Startup provisioning (
Provisioned::apply) runs from the loaded config. - Once landed, id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798's remainder closes: pull policy + freshness consumed from config, and
doc/2026-10-14T_platform_completion/acceptance-brief.mdline 76 checked off.
Acceptance criteria
-
id servewith a config file namingpull_policy = "members"demonstrably refuses a non-member pull in a test, and with no config file behaves exactly as today - A malformed config file fails
id servestartup with the parse error named - The configured freshness window reaches the seitan admission check that serve runs (test at the configured value, not the 5-minute default)
- id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798's remaining acceptance items are verified against this change and id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798 is closed or its remainder re-scoped
Out of scope
- Changes to the
[policy]/[budgets]parse surface itself (landed, PR id(server_config): [policy] table for freshness window + pull policy (#798) #1801) - Blob gating (
blob_gatealready requires membership independently)
🤖 Agent note · filed
- Agent: queue worker (repo-worker-code), lane code-e
- Session / ID: task 2657
- Found via: queue claim — resume of id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798's blocked remainder
- Task: Filed from task 2657's re-verification: the consumption point id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798 waits on does not exist as production code; this issue names it so the block is a tracked dependency instead of a note.
- Expectation: effort l; done = the acceptance criteria above.
- Links: task 2657 (queue); issue id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798; PR id(server_config): [policy] table for freshness window + pull policy (#798) #1801
Metadata
Metadata
Assignees
Labels
app/idPackage/app: id (pkgs/ or apps/ in this repo)Package/app: id (pkgs/ or apps/ in this repo)effort/lLarge: multi-day or open-ended; expect staged check-insLarge: multi-day or open-ended; expect staged check-inskind/featureNew feature or capability requestNew feature or capability requestpriority/normalOrdinary priority (the default)Ordinary priority (the default)source/queue-workerFiled or worked by the queue/worker pilotFiled or worked by the queue/worker pilot
Activity
dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up
id serveServerConfig consumption integration that unblocks issue id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798dezren39 commentedon Nov 3, 2026
🤖 Agent note · triaged
id serveServerConfig consumption integrationVerification (fresh at main
5b0aeb593c0c9bfcf14c2c9980fee82e484ac7e6, laptop primary)Every claim in this issue re-verified; the integration is still entirely missing:
ServerConfig::loadhas no production caller: searchingServerConfig::load/server_config::acrosspkgs/id/srchits onlyserver_config/{mod,parse,provision}.rsand a doc mention atpull_policy.rs:22.pkgs/id/src/commands/serve.rshas zeroserver_config/ServerConfigreferences. The only productionPullGateiscrate::event_sync::open_gate()atserve.rs:1284—event_sync.rs:74hard-codesPullPolicy::Openover theNoWorldsstub ("local-events").seitan::admit(seitan/admit.rs:155) is referenced only insideseitan/itself and byserver_config'sFreshnessplumbing; serve runs no seitan admission at all today.Freshnessis constructed in production nowhere outsideserver_config::freshness(), which nothing calls.Provisioned::applyappears only inserver_config/mod.rsandserver_config/provision.rs— no production caller.pull_policy.rs:22-23still says it plainly: "id servedoes not read it yet, and no session builds a gate from config."doc/2026-10-14T_platform_completion/acceptance-brief.mdline 76 (the id phase-8/platform-completion: freshness-window and pull-policy config are not wired into server/world settings or CLI defaults #798 close-out item) is still unchecked.(Line drift since filing: the
open_gate()call moved fromserve.rs:1256toserve.rs:1284.)Scoped slices, in order
Slice 1 — serve loads the config (foundation; unblocks everything). A server-config path flag on
id servein the existing CLI style; absent flag = today's behaviour exactly (code defaults, no file read). A malformed file fails startup with theServerConfig::parseerror named.Provisioned::applyruns at startup from the loaded config. Covers acceptance criterion 2 and the no-config half of criterion 1. Routed: task 8839 (queuerepo-health-code-pilot,small_fix, dedupe keyrepo-health:v1:fix:developing-today/code:issue:5119— already queued when this triage enqueued against it; packet preserved in the goal's shift-tools aspacket-5119-slice1.json).Slice 2 — pull gate from config. Serve builds its sync gate(s) from
config.pull_policy()instead of the hard-codedopen_gate(). The world-less own-store case needs its decision made in this slice, not discovered in it — recommendation: underpull_policy = "members", a store with no membership source refuses startup with a clear error naming exactly that, rather than silently serving open (which would defeat the configured policy) or silently refusing every pull at runtime (which is undebuggable). Covers acceptance criterion 1 (amembersconfig demonstrably refuses a non-member pull in a test). Depends on slice 1.Slice 3 — freshness consumer. Wire
config.freshness()into the seitan admission path. Scoping caveat found in triage: serve currently exposes no seitan admission entry point, so this slice includes naming/building that consumer where invite admission is actually served (start fromseitan/accept.rs+seitan/admit.rs), not just passing a value. Test at the configured window, not the 5-minuteDEFAULT_WINDOW. Covers acceptance criterion 3. Depends on slice 1; independent of slice 2.Slice 4 — #798 close-out. Verify #798's remaining acceptance items against slices 1–3, check off acceptance-brief line 76, and close #798 or re-scope its remainder explicitly. Depends on slices 1–3.
Ordering / blockers
Slice 1 → (slice 2 ∥ slice 3) → slice 4. No external blockers; the only open decision is slice 2's world-less-store behaviour, with the recommendation above recorded for the implementer — it does not need Drew unless the implementer wants a different default than fail-closed-at-startup.
1 remaining item
dezren39 commentedon Nov 3, 2026
🤖 Agent note · slice 1b scoped (follow-on to slice 1)
id serveload the ServerConfig via--server-configand runProvisioned::applyat startup. Codex's P1 is correct that this is not yet live: the provisioning lands in a fresh in-memoryProvisioned, while live serving builds state fromdirectory.jsonl(world_store::open_world) and the groups log — so configured users/groups are not yet available to live serving and a restart reports them newly created again.serve_groups_log_path;GroupLogneeds an append for already-formed events, since provisioned events carry precomputed ids), provisioned accounts into the directory state serving loads — seeded from what is already persisted so a restart creates nothing and reports zero. Include the design call on unsigned config-derived events (the config holds public keys only, per server_config/provision.rs). Packet draft: hidden_files/packet-5119-slice1b.json in the goal workspace (the plain fix dedupe key for id(serve): no production caller for ServerConfig — load it in id serve and consume [policy] (pull gate, freshness) + provisioning #5119 is held by task 8839, so this slice's enqueue should be cut by the triage/producer pass once slice 1 is terminal, or under a fresh key the producer assigns).feat(id): id serve loads ServerConfig + startup provisioning (#5119 s…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (slice 1)
id serve --server-config <path>loads the ServerConfig before any startup work (malformed/missing file fails startup naming the parse error and path),Provisioned::applyruns from the loaded config with its report on the startup status line, and the loaded state stays in startup scope for slices 2/3. No flag = no file read, behaviour unchanged; a no-worldbuild rejects the flag loudly like--web.cargo test --lib -- server_config60 passed (incl. 4 new serve tests: provisioning applied + idempotent re-apply, malformed fails, missing fails, flag defaults to None);cargo test --lib -- commands::serve37 passed; rustfmt (edition 2024) clean on touched files. The one basic PR check stayed QUEUED (CI runs on main per the standing rule).