Allow device to register with remote info in its .dropbear/root.toml #14
Labels
No labels
agent
blocked
agent
new
agent
review
agent
working
complexity
high
complexity
low
priority
high
priority
low
priority
medium
risk
high
risk
low
risk
medium
type
bug
type
chore
type
feature
type
security
No milestone
No project
No assignees
4 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
tfks/dropbear#14
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
To make life simpler for new device registrations, root.toml files could be shared, so when the target dir contains .dropbear/root.toml already, then use its values as defaults for the
register --remote-*cli args.Brief — QA
Phase: default. Run
fjx qa prompt defaultfor the cycle protocol.PR: #17.
Context
[remote]defaults from an existingroot.tomlforregister --remote-*. Commit45d9860also relaxesconfig.Init: it now overwrites a matching-root_idroot.toml when the requesteddevice_iddiffers from the on-disk one (genuine new-device registration without--force); samedevice_idstill requires--force; a differingroot_idis still refused as a relabel. Review and adversarially probe this guard logic — it is the higher-risk half and is not covered by the PR description.just validatetest::audit(govulncheck) gate fails on 3 Go stdlib vulns (GO-2026-5036/5037/5038, fixed in go1.26.4; toolchain go1.26.3) in unrelated files. This reproduces on cleanorigin/mainand is environmental — do not send back to dev for it.Ledger for: agent-pm
Status: closed @ 2026-06-26T23:35:31.672Z
Briefs:
Activity
(PM manages this ledger; agent section unused)
Ledger for: agent-dev
Status: review @ 2026-06-26T22:39:05.850Z
Refs: #17
Rework — PR #17 (mode inheritance)
Scope: the single fix
$FJX_OWNERscoped from the QA ledger — inheritmodefrom an existing.dropbear/root.toml, symmetrically with the[remote]defaults. The two explicitly out-of-scope QA items (created_atre-stamp, same-host typo overwrite / no-force guard) were left untouched.Fix — commit
eeff880--modeflag default changed from"bidirectional"to""(help text updated to note the inherited default).registerExecutenow resolves mode the same way[remote]is resolved: explicit--modewins; else inherit from the on-diskroot.toml; else fall back to"bidirectional".loadModeDefault(path)mirroringloadRemoteDefaults— readsmodefrom an existing.dropbear/root.toml, returns""when absent/unreadable/invalid.--modeagainst a sharedupload-onlyroot now keepsupload-onlyinstead of silently downgrading tobidirectional.Test —
TestRegisterInheritsModeFromExistingRootTOMLTable-driven, two subtests against a seeded
mode = "upload-only"root:--modeomitted → writtenroot.tomlkeepsupload-only(the previously-untested inheritance path).--mode download-only→ overrides todownload-only.Both pass; full suite
go test ./...→ 772 passed.Validation
just check(format/vet/lint) clean.just validate's only failure istest::audit(govulncheck GO-2026-5037/5038/5039), which is environmental: toolchain is go1.26.3, all three are fixed in go1.26.4, and every reported trace is in pre-existing code (deviceregistry/objectstore/statusapi/main) untouched by this diff. This diff adds no dependencies. Matches the env-failure QA already recorded on this PR.@agent-pm tooling issues should be fixed. Have agent-dev try again.
Ledger for: agent-qa
Status: concerns @ 2026-06-26T22:17:01.863Z
QA review — PR #17 (commit
45d9860)Verdict: concerns — relaxing
config.Init's no-force guard widens the silent-clobber surface in a way the PR description, issue, and tests don't cover. Nothing is outright broken; the guard logic is sound, but a same-host typo now succeeds silently where it used to error, and silently resetsmode.Action summary
validate.yamlrun #29 on head45d9860: success (the only workflow on the PR head). No failed required checks.test::audit(govulncheck) failure noted in the brief is environmental (GO-2026-5036/5037/5038, fixed in go1.26.4; toolchain go1.26.3) and reproduces on cleanorigin/main— not attributable to this diff. Not sent back for it.go build ./...clean;go test ./internal/config/ ./cmd/dropbear/→ 169 passed.What I verified (guard is sound where it counts)
requestedDeviceIDis user-supplied and required (register.go:70), not auto-generated, so the newresult.ObservedDeviceID != requestedDeviceIDclause is not trivially defeated by per-invocation randomness. Good — that was my first hypothesis and it's falsified.StateOnline,root.tomlparsed cleanly, soObservedDeviceIDis always a non-empty, pattern-valid id (validate.go:125-160,roottoml.go:125). The "empty observed device_id always overwrites" edge is unreachable — a missing/invaliddevice_idyieldsStateIdentityCorrupt, notStateOnline. Good.EnsureRootNotInitializedreturns nil when a registry already exists (registry.go:277-297), so the copy-root.toml-to-a-fresh-dir / join-existing-root workflow flows through toInitand exercises the new path.Confirmed issue — silent, mode-resetting clobber on a same-host re-register (medium)
Pre-PR, every no-force re-init against an existing matching-
root_idroot.tomlwas refused withINIT_ALREADY_INITIALIZED. Post-PR, any differingdevice_idoverwrites silently with exit 0. Concretely, a mistyped--device-idon the same machine (e.g.laptop→laptpo) now:root.toml(reproduced with a throwawayconfigtest, since removed: differing device_id,force=false,Initreturns nil and the file is rewritten).mode:register.goinherits[remote]from the existingroot.tomlvialoadRemoteDefaults, butmodeis not inherited — it falls back to the flag defaultbidirectional(register.go:46). A new/typo device that omits--modesilently downgrades a sharedupload-onlyroot tobidirectional. Verified:mode "upload-only" -> "bidirectional"with no warning.deviceregistry.Register(f.deviceID)runs atregister.go:149, beforeInit. This phantom write already happened pre-PR too, but pre-PR the command then exited non-zero (INIT_ALREADY_INITIALIZED), giving the user a signal. Post-PR the command exits 0, so the only signal that a re-register went wrong is now gone.Net: the safety net that caught all accidental re-inits now catches only the exact-same-
device_idcase, and the new path silently rewritesmode.(Note:
root.toml'screated_atis also re-stamped on overwrite, but that field is write-only — never read for any decision, never surfaced in output, and stamped with each device's localtime.Now()on every write since the schema's inception, so it has never represented a root-level creation time. Re-stamping it is harmless; not a finding.)Gap analysis (what CI/tests didn't cover)
TestInit_newDeviceSameRootNoForceonly asserts the happy path (new device succeeds,device_idupdated). It does not assert what happens tomodeon overwrite, so the silent mode-reset is untested.[remote]inheritance andmodenon-inheritance in the register command.Untested assumption / open question for dev
bidirectionalfor a device that omits--modeagainst a shared non-bidirectional root intended? If so, a one-line note in the register help / brief would close the gap. If not,modeshould be inherited from the existingroot.tomlsymmetrically with[remote].Recommendation
Send back to dev to either (a) inherit
modealongside[remote]on register, or (b) consciously document the new silent-overwrite semantics (mode reset on differingdevice_idwithout--force) in the PR body and register help, and add a test pinning the chosen behavior.Routing note (fjx)
fjx qaexposes no hand-off/assign verb (onlynext,ledger,checks,release,prompt);fjx issueislist/view/labelonly — there is nofjx qa donemirroringfjx dev done. I'm therefore signalling the verdict via this ledger + the existingagent/reviewlabel rather than reassigning the issue myself. If QA is expected to reassign toagent-devon a concerns verdict, that capability is missing at the CLI.@agent-pm after discussing with @agent-qa kick this back to @agent-dev to make sure that
modegets inherited from the root.toml as well - my example tricked him into thinking it was only the --remote-* fields. We can ignore the concerns about created_at and the typo-on-same-hostBrief — Dev (rework)
Phase: simple. Run
fjx dev prompt simplefor the cycle protocol.PR: #17. Resume the same worktree /
<type>/<slug>branch / PR — this is rework on the existing diff, not a new branch or PR.QA Findings
QA reviewed PR #17 (commit
45d9860) and returned concerns. After discussion,$FJX_OWNERhas scoped this rework to a single fix — ignore the rest of the QA ledger's items.Fix: inherit
modefrom an existing.dropbear/root.toml, symmetrically with the[remote]fields.registeralready inherits the[remote]defaults from an existingroot.tomlvialoadRemoteDefaults, butmodeis not inherited — it falls back to the flag defaultbidirectional(register.go:46). The original issue example only mentioned the--remote-*fields, which is what mademodeget missed; the intent is for a sharedroot.tomlto seed all of its reusable defaults,modeincluded. As-is, a device that omits--modeagainst a sharedupload-onlyroot silently downgrades it tobidirectional.Make
modeinherit from the on-diskroot.tomlwhen--modeis not explicitly set on the command line, the same way[remote]defaults already do. Add a test pinning the behavior (the existingTestInit_newDeviceSameRootNoForce/ register tests don't covermodeon the inheritance path).Explicitly out of scope (do NOT address)
Per
$FJX_OWNER, ignore these QA items entirely:created_atre-stamp on overwrite (write-only field, harmless).config.Initno-force guard stays as-is.Stay strictly within the
mode-inheritance fix. When done, re-runjust validate(skip only if no code changed), thenfjx dev done 14.