Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Developer/BACK_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
| BL-21 | Daemon | `dind` persists no logs to disk | `configure_logging()` (`dincli/dind/logging.py` — lands with [PR #32](https://github.com/InfiniteZeroFoundation/DevNet/pull/32), not yet on `develop`) attaches a plain `StreamHandler` (stderr) with the `JsonFormatter` — no `RotatingFileHandler`, nothing written into `StateDirs` despite it already holding `jobs.db`/`dind.pid`/`preferences.json`. Under systemd (journald) or a container log driver the supervisor persists logs; run directly in a terminal — the documented and tested path — stderr is gone when the session closes, leaving nothing to `grep` for "why did my node skip a job three hours ago". For an always-on daemon aimed at non-expert operators (issue #21), `dind` should own a rotating log file under its own state dir. | P4-1.1 (operability, before `dind` is load-bearing) | PR #32 code review finding No. 6, Jul 30, 2026 | 🟢 Fixed on the PR branch, unmerged — [PR #32](https://github.com/InfiniteZeroFoundation/DevNet/pull/32)'s `dincli/dind/logging.py` adds a `RotatingFileHandler` in the state directory when `state_dir` is given, alongside stderr. Lands with PR #32. Checked 2026-09-30 |
| BL-22 | Daemon / SDK | `NonceManager._instances` never evicted | `NonceManager` (`dincli/sdk/tx.py` — lands with [PR #31](https://github.com/InfiniteZeroFoundation/DevNet/pull/31), not yet on `develop`) keys its per-`(chain_id, address)` cache in a class-level `_instances` dict with no eviction, so it grows for the process lifetime. Correct and irrelevant for the CLI (one invocation per process), but it's process-wide mutable state — worth a look once `dind` runs long-lived. Already caused real test pollution: reservations leaked between test classes until each cleared `NonceManager._instances` in `setup_method`. | P4-1.1 (before `dind` runs long-lived) | `task_300726_8` implementation note, Jul 31, 2026 | 🟢 Fixed on the PR branch, unmerged — [PR #31](https://github.com/InfiniteZeroFoundation/DevNet/pull/31)'s `dincli/sdk/tx.py` bounds `_instances` at `_MAX_INSTANCES` (strong cache, with live instances tracked separately so an in-flight reservation isn't dropped). Lands with PR #31. Checked 2026-09-30 |
| BL-23 | DP / Privacy (cache_model_0) | `clip_scope: global` default paired with an unreviewed `clipping_norm: 1.0` may over-clip real weights | [PR #109](https://github.com/InfiniteZeroFoundation/DevNet/pull/109) (`fix/dp-sensitivity`) correctly ties noise to the clip (`noise_scale = noise_multiplier * clipping_norm`) and defaults `clip_scope` to `global` so the clip actually bounds the combined L2 norm the noise is calibrated against — the sensitivity-calibration fix itself is sound (`per_layer` only bounds the combined norm at `clipping_norm * sqrt(n)`, not `clipping_norm`, so pairing it with the new noise formula would under-noise as tensor count grows). But `cache_model_0/manifest.json`'s `clipping_norm: 1.0` was never revisited: under the old `per_layer` scope it bounded each tensor independently to norm 1.0; under `global` it bounds the *entire model's combined* L2 norm to 1.0, a much tighter constraint for any model with more than one floating tensor (`sqrt(Σ‖tensor_i‖²)` grows with tensor count even if no individual tensor's norm changes). No test in PR #109 exercises this against `cache_model_0`'s real trained `state_dict` (the new tests use synthetic tensors), so it's unverified whether the new default clips — and thus degrades — the reference model's weights far more aggressively than before. Follow-up: run `apply_dp_mechanism`/`clip_state_dict` against `cache_model_0`'s actual trained weights under the new default and retune `clipping_norm` if the combined-norm bound turns out to be destructive. | P3 (verify before/at merge) | PR #109 review, Sep 8, 2026 | ✅ Fixed — PR No. 263 |
| BL-24 | DP / Privacy (cache_model_0) | F4 — Laplace noise calibrated against an L2 clip, not the L1 sensitivity it's normally calibrated against | `post_training_laplace`'s `laplace_scale` is scaled by the same `clipping_norm` as the Gaussian mechanisms (`clip_state_dict`'s L2-norm clip), but the Laplace mechanism's textbook privacy guarantee is calibrated against L1 sensitivity, not L2. [PR #109](https://github.com/InfiniteZeroFoundation/DevNet/pull/109) flagged this explicitly rather than silently assuming it's fine (`Documentation/technical/services/clients.md:210-212`: "Laplace noise calibrated against an L2 clip is an open question tracked separately"), and [#99](https://github.com/InfiniteZeroFoundation/DevNet/issues/99)'s F4 (`Documentation/technical/audits/dp-mechanism-review.md` §F4) called the structural mismatch confirmed but left the exact magnitude/severity for a DP specialist's sign-off — explicitly excluded from #99's scope rather than fixed. [#119](https://github.com/InfiniteZeroFoundation/DevNet/pull/119) (which closed #99's remaining F8 items) left F4 untouched, so nothing currently tracks it now that #99 is closed. Needs either a DP specialist's opinion that L2-calibrated Laplace is acceptable as-is (and the open-question note downgraded to an explanation), or a fix (e.g. recalibrating against an actual L1 clip, or reclassifying `post_training_laplace` as experimental alongside F5's `per_layer` treatment) before any ε is claimed for it. | P3/P4 (needs DP specialist input first) | [#99](https://github.com/InfiniteZeroFoundation/DevNet/issues/99) F4 (excluded from scope), `Documentation/technical/audits/dp-mechanism-review.md` §F4, Sep 10, 2026 | 🟡 Partially addressed — [issue #279](https://github.com/InfiniteZeroFoundation/DevNet/issues/279) Track A reclassified both `post_training_gaussian` and `post_training_laplace` as experimental (F5's recommended fix): `resolve_dp_config` now logs a warning on selection, and `Documentation/technical/services/clients.md` labels both accordingly. F4's actual L2-vs-L1 mismatch is still unfixed — needs a DP specialist's recommendation per issue #279 Track B before `post_training_laplace` can carry any ε |
| BL-24 | DP / Privacy (cache_model_0) | F4 — Laplace noise calibrated against an L2 clip, not the L1 sensitivity it's normally calibrated against | `post_training_laplace`'s `laplace_scale` is scaled by the same `clipping_norm` as the Gaussian mechanisms (`clip_state_dict`'s L2-norm clip), but the Laplace mechanism's textbook privacy guarantee is calibrated against L1 sensitivity, not L2. [PR #109](https://github.com/InfiniteZeroFoundation/DevNet/pull/109) flagged this explicitly rather than silently assuming it's fine (`Documentation/technical/services/clients.md:210-212`: "Laplace noise calibrated against an L2 clip is an open question tracked separately"), and [#99](https://github.com/InfiniteZeroFoundation/DevNet/issues/99)'s F4 (`Documentation/technical/audits/dp-mechanism-review.md` §F4) called the structural mismatch confirmed but left the exact magnitude/severity for a DP specialist's sign-off — explicitly excluded from #99's scope rather than fixed. [#119](https://github.com/InfiniteZeroFoundation/DevNet/pull/119) (which closed #99's remaining F8 items) left F4 untouched, so nothing currently tracks it now that #99 is closed. Needs either a DP specialist's opinion that L2-calibrated Laplace is acceptable as-is (and the open-question note downgraded to an explanation), or a fix (e.g. recalibrating against an actual L1 clip, or reclassifying `post_training_laplace` as experimental alongside F5's `per_layer` treatment) before any ε is claimed for it. | P3/P4 (needs DP specialist input first) | [#99](https://github.com/InfiniteZeroFoundation/DevNet/issues/99) F4 (excluded from scope), `Documentation/technical/audits/dp-mechanism-review.md` §F4, Sep 10, 2026 | ✅ Resolved (qualified) — [issue #279](https://github.com/InfiniteZeroFoundation/DevNet/issues/279) Track A reclassified both `post_training_gaussian` and `post_training_laplace` as experimental (F5's recommended fix): `resolve_dp_config` now logs a warning on selection, and `Documentation/technical/services/clients.md` labels both accordingly. Track B then adds `update_laplace`, fixing F4's L2-vs-L1 mismatch: it mirrors `update_gaussian`'s delta-level clipping, but clips the delta's **L1** norm instead of L2, so `clipping_norm` is the norm the Laplace mechanism's noise is actually calibrated against. `post_training_laplace` itself remains unchanged and experimental (F5). Under a stated neighbor definition (client-level DP: one neighbor includes a client's update, the other replaces it with a zero contribution), this gives an L1 sensitivity of `clipping_norm` and an (ε, 0)-DP guarantee at `laplace_scale = clipping_norm / ε` under that definition — not yet specialist-reviewed, and non-floating (integer) buffers in the state dict still pass through unprivatized, presumed non-sensitive |
| BL-25 | Tooling / reference model (cache_model_0) | `cache_model_0/abis/` task-contract artifacts are stale vs. `foundry/src` | `cache_model_0/abis/DINTaskCoordinator.json` and `DINTaskAuditor.json` are full hardhat artifacts (abi + bytecode) last regenerated 2026-06-09, missing 67 ABI entries present in `foundry/src` for the coordinator (104 vs 170) and 96 for the auditor (68 vs 158), with pre-foundry constructors. [PR #171](https://github.com/InfiniteZeroFoundation/DevNet/pull/171) regenerated the six bundled `dincli/abis/` files from `foundry/out` but deliberately left these alone: [cache_model_0/manifest.json](../cache_model_0/manifest.json)'s `task_contracts` block pins each artifact to an IPFS CID, records `"type": "hardhat-artifact"` and a hardhat/cancun/optimizer-off `compilation` block, and carries deployed addresses, and dincli resolves task artifacts by CID. Regenerating the files locally would leave the manifest describing artifacts it no longer points to. Needs one pass: regenerate both from `foundry/out` (with bytecode, e.g. `dincli system dump-abi --bytecode --output cache_model_0/abis`), update the manifest's artifact type and compilation metadata to foundry, re-pin to IPFS and update the CIDs. Addresses only change on a redeploy. | P3/P4 | PR #171 merge (2026-09-26): out of scope for the PR's ABI refresh | 🟡 Fix in review — [PR #261](https://github.com/InfiniteZeroFoundation/DevNet/pull/261) regenerates both ABIs from `foundry/out` and updates `cache_model_0/manifest.json` (changes requested, Oct 22); tracked in [#246](https://github.com/InfiniteZeroFoundation/DevNet/issues/246) |
| BL-26 | Solidity/foundry (task contracts) | Batch-assignment seed lock (H-2) shares BL-11's re-roll residual, plus a new pool-reshaping gap | `DINTaskCoordinator.autoCreateTier1AndTier2`/`createAuditorsBatches` (task_240926_18 Part B, issue #156 H-2 aggregation side) reuse BL-11's future-block-seed + permissionless-lock pattern (`lockAggSeed`/`lockAuditSeed`), so they inherit its residual (2): the model owner can decline to lock a seed they dislike and wait out the ~256-block `blockhash` window for a fresh draw — repeatable, since nothing locks automatically today. A second, distinct gap not present in BL-11's `_assignFreshSubgroup` (which shuffles a fixed pool and only lets an exiting validator drop itself, not re-roll the rest): `_activeAggregatorPool`/`_activeAuditorPool` are evaluated at `autoCreateTier1AndTier2`/`createAuditorsBatches` call time, *after* the seed is already public, and Fisher-Yates re-rolls the whole assignment on any pool-size change — so a validator can unstake between lock and create to reshape everyone else's batch. Cost to the attacker is real but modest (their own Sybils sit out the GI and enter unbonding). Ready-made fix for the pool-reshaping gap: adopt `_assignFreshSubgroup`'s pattern — shuffle the fixed per-GI registration list (`dinAggregators[_GI]` / the auditor equivalent) with the locked seed, then skip inactive validators while filling seats, so an unstake only forfeits the leaver's own seat instead of re-rolling everyone else's. | P3/P4 | [PR #191](https://github.com/InfiniteZeroFoundation/DevNet/pull/191) review, Sep 29, 2026 | 🟡 Partially mitigated — the decline-to-lock re-roll is narrowed by a validator-side lock in dincli, added at the PR #191 merge (`dincli aggregator lock-seed` / `dincli auditor lock-seed`, and automatically in `show-t1-batches`/`show-t2-batches`/`lms-evaluation show-batch` before batches exist): any validator online after the seed block locks it, so the owner only gets a re-roll if nobody else is. A contract-side cap on re-anchors was considered and deferred: with no GI-abort path, a GI capped out would be stuck forever (`endGI` needs `AggregatorsSlashed`, `startGI` needs `GIended`), locking validators' registration slots and the reward pool — it needs a GI-abort design (who may abort, where the reward pool goes) first. Pool-reshaping gap unaddressed. Documented as residuals in the PR (`DINTaskCoordinator.md` §6.3). Sequencer-trust residual (shared with BL-11) tracked in [issue #178](https://github.com/InfiniteZeroFoundation/DevNet/issues/178); the pool-reshaping gap is now [#243](https://github.com/InfiniteZeroFoundation/DevNet/issues/243) (fix in review, [PR #253](https://github.com/InfiniteZeroFoundation/DevNet/pull/253)); the re-roll-by-declining-to-lock gap has no dedicated issue yet, same as BL-11's own un-issued residual (2) |
| BL-27 | dincli (model owner) | `dincli model-owner deploy` still uses the pre-foundry task-contract constructors | `dincli/cli/modelownerd/deploy.py` sends `DINTaskCoordinator.constructor(stake)` (`:35`) and `DINTaskAuditor.constructor(stake, coordinator)` (`:77`), but `foundry/src` takes `(stake, modelId)` and `(stake, coordinator, modelId)`. Against foundry artifacts, which are the bundled `dincli/abis/` since PR #171, the deploy fails at ABI encoding, so model owners can't deploy task contracts from dincli. The `tests/dincli/` harness hides this because it deploys task contracts from **hardhat** artifacts. The fix also has to settle where `modelId` comes from: the registry assigns it only at approval, after the contracts exist (`DINTaskCoordinator.md` §10 No. 4). | P3 (before any model-owner onboarding on DevNet 3.0) | PR No. 204 review, Sep 30, 2026 (caveats `DINTaskCoordinator.md` §10 No. 10, `DINTaskAuditor.md` §13 No. 8) | 🟡 Fix in review — [PR #261](https://github.com/InfiniteZeroFoundation/DevNet/pull/261) adds `--model-id` and passes it to both constructors (changes requested, Oct 22); tracked in [#223](https://github.com/InfiniteZeroFoundation/DevNet/issues/223) Part 1 |
Expand Down
Loading
Loading