feat(trust): full Duniter web-of-trust membership (params + referents)
Slice 4 of Block 2. The pure rule was already parameterised; this adds the policy, cold-start and UI around it. - commons_core: WotParams (sigQty/stepMax/sigValidity, Duniter defaults) + WebOfTrust.membersWith; npubToHex helper (NIP-19 decode) for adding roots. - WotSettings (keystore): the active parameters, configurable — a young network loosens them and tightens as it grows, as Ğ1 did. Defaults Duniter. - TrustReferents: the bootstrap 'seeds' membership is measured from — a bundled asset (empty until real founders are curated, no invented keys) unioned with referents the user adds by npub/QR. Honest cold-start. - TrustCubit: computes the full membership verdict against referents+params alongside the personal circle, and exposes a TrustTier (networkMember > inYourCircle > vouched > unknown). Certifications issued with the active validity (they expire and renew, Duniter rule). - UI: chat trust badge by tier; a 'Network of trust' screen (manage roots + advanced params) reached from the profile. i18n en/es/pt/ast. Tests: WotParams/membersWith, npubToHex, TrustReferents, WotSettings, and TrustCubit tiers/membership. Resolves the WoT-parameters decision (open-decisions §B). Trust net stays empty/undetermined until seeded — by design; users bootstrap their own roots.
This commit is contained in:
parent
a96049dd36
commit
4cf53f259f
29 changed files with 1111 additions and 39 deletions
|
|
@ -91,6 +91,55 @@ void main() {
|
|||
await outside.close();
|
||||
});
|
||||
|
||||
test('network membership: enough referent vouches → member', () async {
|
||||
const params =
|
||||
WotParams(sigQty: 2, stepMax: 5, sigValidity: Duration(days: 365));
|
||||
final transport = FakeTrustTransport(me)
|
||||
..addCert('r1', peer)
|
||||
..addCert('r2', peer);
|
||||
final cubit = TrustCubit(
|
||||
transport,
|
||||
peerPubkey: peer,
|
||||
selfPubkey: me,
|
||||
referents: {'r1', 'r2'},
|
||||
params: params,
|
||||
);
|
||||
await cubit.load();
|
||||
expect(cubit.state.networkBootstrapped, isTrue);
|
||||
expect(cubit.state.isNetworkMember, isTrue);
|
||||
expect(cubit.state.tier, TrustTier.networkMember);
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
test('with no referents, membership is undetermined (not a member)',
|
||||
() async {
|
||||
final transport = FakeTrustTransport(me)
|
||||
..addCert('r1', peer)
|
||||
..addCert('r2', peer);
|
||||
// referents default to {} → the trust net isn't seeded.
|
||||
final cubit = TrustCubit(transport, peerPubkey: peer, selfPubkey: me);
|
||||
await cubit.load();
|
||||
expect(cubit.state.networkBootstrapped, isFalse);
|
||||
expect(cubit.state.isNetworkMember, isFalse);
|
||||
await cubit.close();
|
||||
});
|
||||
|
||||
test('tier falls back to vouched, then unknown', () async {
|
||||
final vouched = TrustCubit(
|
||||
FakeTrustTransport(me)..addCert('someone', peer),
|
||||
peerPubkey: peer,
|
||||
selfPubkey: me);
|
||||
await vouched.load();
|
||||
expect(vouched.state.tier, TrustTier.vouched);
|
||||
await vouched.close();
|
||||
|
||||
final unknown = TrustCubit(FakeTrustTransport(me),
|
||||
peerPubkey: 'nobody', selfPubkey: me);
|
||||
await unknown.load();
|
||||
expect(unknown.state.tier, TrustTier.unknown);
|
||||
await unknown.close();
|
||||
});
|
||||
|
||||
test('never vouches for self', () async {
|
||||
final cubit =
|
||||
TrustCubit(FakeTrustTransport(me), peerPubkey: me, selfPubkey: me);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue