release: prepare v0.9.7

This commit is contained in:
BigBodyCobain
2026-05-01 22:56:50 -06:00
parent ea457f27da
commit 28b3bd5ebf
670 changed files with 187059 additions and 14005 deletions
+182 -14
View File
@@ -1,4 +1,5 @@
import type { Contact } from '@/mesh/meshIdentity';
import { getContactTrustSummary, rootWitnessIdentityLabel } from '@/mesh/contactTrustSummary';
export type PrivateLaneHint = {
severity: 'warn' | 'danger';
@@ -31,22 +32,68 @@ export function shortTrustFingerprint(fingerprint: string | undefined): string {
return `${value.slice(0, 8)}..${value.slice(-6)}`;
}
export function isInvitePinnedFirstContact(contact?: Partial<Contact> | null): boolean {
return getContactTrustSummary(contact)?.state === 'invite_pinned';
}
export function isFirstContactTrustOnly(contact?: Partial<Contact> | null): boolean {
return getContactTrustSummary(contact)?.state === 'tofu_pinned';
}
export function hasKnownFirstContactAnchor(contact?: Partial<Contact> | null): boolean {
if (!contact) return false;
if (contact.remotePrekeyMismatch || contact.verify_mismatch || contact.verified) return false;
if (contact.verify_registry || contact.verify_inband) return false;
return Boolean(contact.remotePrekeyFingerprint || contact.remotePrekeyPinnedAt);
return Boolean(
contact.dhPubKey ||
contact.sharedAlias ||
contact.remotePrekeyFingerprint ||
contact.remotePrekeyObservedFingerprint ||
contact.remotePrekeyPinnedAt ||
contact.invitePinnedTrustFingerprint ||
contact.invitePinnedDhPubKey ||
contact.invitePinnedAt ||
contact.verified ||
contact.verify_registry ||
contact.verify_inband ||
String(contact.trust_level || '').trim(),
);
}
export function hasVerifiedFirstContactAnchor(contact?: Partial<Contact> | null): boolean {
const summary = getContactTrustSummary(contact);
return Boolean(summary?.verifiedFirstContact);
}
export function requiresVerifiedFirstContact(contact?: Partial<Contact> | null): boolean {
return !hasVerifiedFirstContactAnchor(contact);
}
export function requiresExplicitTofuDowngrade(contact?: Partial<Contact> | null): boolean {
return !hasKnownFirstContactAnchor(contact);
}
export function shouldAutoRevealSasForTrust(contact?: Partial<Contact> | null): boolean {
if (!contact) return false;
const summary = getContactTrustSummary(contact);
if (!summary) return false;
return Boolean(
contact.remotePrekeyMismatch || contact.verify_mismatch || isFirstContactTrustOnly(contact),
summary.state === 'tofu_pinned' ||
summary.state === 'mismatch' ||
summary.state === 'continuity_broken' ||
summary.registryMismatch,
);
}
export function dmTrustPrimaryActionLabel(contact?: Partial<Contact> | null): string {
return isFirstContactTrustOnly(contact) ? 'VERIFY SAS NOW' : 'SHOW SAS';
const action = getContactTrustSummary(contact)?.recommendedAction;
if (action === 'import_invite') {
return 'IMPORT INVITE';
}
if (action === 'verify_sas') {
return 'VERIFY SAS NOW';
}
if (action === 'reverify') {
return 'REVERIFY NOW';
}
return 'SHOW SAS';
}
export function buildPrivateLaneHint(opts: {
@@ -82,25 +129,37 @@ export function buildPrivateLaneHint(opts: {
) {
return {
severity: 'warn',
title: 'TRANSITIONAL PRIVATE LANE',
title: 'CONTROL-ONLY PRIVATE LANE',
detail:
'INFONET gate chat is available, but the strongest transport posture is still warming up. Treat metadata resistance as reduced until Reticulum is ready.',
'Gate chat is available once Wormhole is ready, but this setup is still only PRIVATE / CONTROL_ONLY. Content stays encrypted, while metadata resistance is reduced until a stronger private carrier comes online. Dead Drop / DM remains the stronger lane.',
};
}
return null;
}
export function buildDmTrustHint(contact?: Partial<Contact> | null): DmTrustHint | null {
if (!contact) return null;
if (contact.remotePrekeyMismatch) {
const summary = getContactTrustSummary(contact);
if (!contact || !summary) return null;
const witnessedRootLabel = rootWitnessIdentityLabel(summary);
if (summary.state === 'continuity_broken' || summary.state === 'mismatch') {
return {
severity: 'danger',
title: 'REMOTE PREKEY CHANGED',
title: summary.state === 'continuity_broken' ? 'CONTINUITY BROKEN' : 'REMOTE PREKEY CHANGED',
detail:
'Pause private DM sending. Refresh the contact, compare the SAS phrase or another trusted fingerprint, then explicitly trust the new prekey only if it checks out.',
summary.rootMismatch
? summary.state === 'continuity_broken'
? summary.rootWitnessed
? `A previously trusted contact changed ${witnessedRootLabel}. Pause private DM sending and replace the signed invite or re-verify SAS before trusting the new key.`
: 'A previously trusted contact changed stable root identity. Pause private DM sending and replace the signed invite or re-verify SAS before trusting the new key.'
: summary.rootWitnessed
? `Pause private DM sending. The observed ${witnessedRootLabel} changed; replace the invite or compare SAS before trusting the new key.`
: 'Pause private DM sending. The observed stable root identity changed; replace the invite or compare SAS before trusting the new key.'
: summary.state === 'continuity_broken'
? 'A previously trusted contact changed identity material. Pause private DM sending and replace the invite or re-verify SAS before trusting the new key.'
: 'Pause private DM sending. Refresh the contact, compare the SAS phrase or another trusted fingerprint, then explicitly trust the new prekey only if it checks out.',
};
}
if (contact.verify_mismatch) {
if (summary.registryMismatch) {
return {
severity: 'danger',
title: 'CONTACT KEY MISMATCH',
@@ -108,7 +167,116 @@ export function buildDmTrustHint(contact?: Partial<Contact> | null): DmTrustHint
'Registry and in-band key evidence disagree for this contact. Re-verify before continuing with private messaging.',
};
}
if (isFirstContactTrustOnly(contact)) {
if (summary.legacyLookup && summary.state === 'sas_verified') {
return {
severity: 'warn',
title: 'LEGACY LOOKUP',
detail:
'This contact is SAS verified, but key refresh still relies on direct agent ID lookup. Import or re-import a signed invite to move off stable-ID lookup before removal.',
};
}
if (
summary.rootAttested &&
!summary.rootWitnessed &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'warn',
title: 'ROOT INTERNAL ONLY',
detail:
summary.state === 'invite_pinned'
? 'This contact is anchored to an internal stable root, but not to witnessed root distribution yet. Re-import a current signed invite to refresh stronger root provenance.'
: 'This contact is SAS verified on an internal stable root, but root distribution is not witnessed yet. Re-import a current signed invite if you want witnessed root provenance too.',
};
}
if (
summary.rootDistributionState === 'single_witness' &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'warn',
title: 'ROOT SINGLE WITNESS',
detail:
summary.state === 'invite_pinned'
? 'This contact is anchored to a single-witness stable root. Re-import a current signed invite if you want stronger quorum witness provenance.'
: 'This contact is SAS verified on a single-witness stable root. Re-import a current signed invite if you want stronger quorum witness provenance too.',
};
}
if (
summary.rootWitnessProvenanceState === 'local_quorum' &&
!(summary.rootWitnessed && Number(summary.rootManifestGeneration || 0) > 1 && !summary.rootRotationProven) &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'warn',
title: 'ROOT LOCAL QUORUM',
detail:
summary.state === 'invite_pinned'
? 'This contact is anchored to a locally quorum-witnessed stable root. The current witness policy is satisfied, but those witnesses are still co-resident in one trust domain.'
: 'This contact is SAS verified on a locally quorum-witnessed stable root. The current witness policy is satisfied, but those witnesses are still co-resident in one trust domain.',
};
}
if (
summary.rootWitnessProvenanceState === 'independent_quorum' &&
!(summary.rootWitnessed && Number(summary.rootManifestGeneration || 0) > 1 && !summary.rootRotationProven) &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'warn',
title: 'ROOT INDEPENDENT QUORUM',
detail:
summary.state === 'invite_pinned'
? 'This contact is anchored to an independently quorum-witnessed stable root instead of first-sight TOFU.'
: 'This contact is SAS verified on an independently quorum-witnessed stable root.',
};
}
if (
summary.rootWitnessed &&
Number(summary.rootManifestGeneration || 0) > 1 &&
!summary.rootRotationProven &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'danger',
title: 'ROOT ROTATION UNPROVEN',
detail:
summary.state === 'invite_pinned'
? 'This contact resolves to a witnessed stable root, but the current root replacement does not carry previous-root proof. Replace the signed invite before treating this root as continuous.'
: 'This contact is SAS verified, but the current witnessed root replacement does not carry previous-root proof. Replace the signed invite before treating this root as continuous.',
};
}
if (
summary.rootDistributionState === 'witness_policy_not_met' &&
(summary.state === 'invite_pinned' || summary.state === 'sas_verified')
) {
return {
severity: 'danger',
title: 'ROOT WITNESS POLICY NOT MET',
detail:
summary.state === 'invite_pinned'
? 'This contact resolves to a witnessed stable root, but the current receipt set does not satisfy the published witness policy. Replace or re-import the signed invite before private use.'
: 'This contact is SAS verified, but the current witnessed root no longer satisfies its published witness policy. Replace or re-import the signed invite before private use.',
};
}
if (summary.state === 'invite_pinned') {
return {
severity: 'warn',
title: 'INVITE PINNED',
detail:
summary.rootAttested
? summary.rootWitnessProvenanceState === 'independent_quorum'
? 'This contact was anchored by an imported signed invite and independently quorum-witnessed stable root identity instead of first-sight TOFU. Keep the invite channel trusted, and use SAS if you want an additional continuity check.'
: summary.rootWitnessProvenanceState === 'local_quorum'
? 'This contact was anchored by an imported signed invite and locally quorum-witnessed stable root identity instead of first-sight TOFU. Keep the invite channel trusted, and use SAS if you want an additional continuity check.'
: summary.rootDistributionState === 'single_witness'
? 'This contact was anchored by an imported signed invite and single-witness stable root identity instead of first-sight TOFU. Re-import a current signed invite if you want stronger quorum witness provenance.'
: summary.rootWitnessed
? 'This contact was anchored by an imported signed invite and witnessed stable root identity instead of first-sight TOFU, but the current witness policy is not satisfied.'
: 'This contact was anchored by an imported signed invite and stable root identity instead of first-sight TOFU. Root distribution is still internal-only.'
: 'This contact was anchored by an imported signed invite instead of first-sight TOFU. Keep the invite channel trusted, and use SAS if you want an additional continuity check.',
};
}
if (summary.state === 'tofu_pinned') {
return {
severity: 'warn',
title: 'FIRST CONTACT (TOFU ONLY)',