From 26d9d1f5020fa963467620e5998d9ac008528895 Mon Sep 17 00:00:00 2001 From: flemming-it Date: Thu, 7 May 2026 17:09:52 +0200 Subject: [PATCH] feat: clearEventLog wrapper (v0.7.1) Picks up the new HubAdmin.ClearEventLog RPC. Exposed as HubClient.clearEventLog(reviewer:, reason:) returning the purged count + active channel for the caller to confirm. Signed-off-by: flemming-it --- lib/src/generated/fai/v1/hub.pb.dart | 125 +++++++++++++++++++++++ lib/src/generated/fai/v1/hub.pbgrpc.dart | 24 +++++ lib/src/generated/fai/v1/hub.pbjson.dart | 28 +++++ lib/src/hub_client.dart | 15 +++ pubspec.yaml | 2 +- 5 files changed, 193 insertions(+), 1 deletion(-) diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index df62854..310d192 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -3860,6 +3860,131 @@ class CuratedModel extends $pb.GeneratedMessage { void clearLicense() => $_clearField(8); } +class ClearEventLogRequest extends $pb.GeneratedMessage { + factory ClearEventLogRequest({ + $core.String? reviewer, + $core.String? reason, + }) { + final $result = create(); + if (reviewer != null) { + $result.reviewer = reviewer; + } + if (reason != null) { + $result.reason = reason; + } + return $result; + } + ClearEventLogRequest._() : super(); + factory ClearEventLogRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClearEventLogRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ClearEventLogRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'reviewer') + ..aOS(2, _omitFieldNames ? '' : 'reason') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ClearEventLogRequest clone() => ClearEventLogRequest()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ClearEventLogRequest copyWith(void Function(ClearEventLogRequest) updates) => super.copyWith((message) => updates(message as ClearEventLogRequest)) as ClearEventLogRequest; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ClearEventLogRequest create() => ClearEventLogRequest._(); + ClearEventLogRequest createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ClearEventLogRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ClearEventLogRequest? _defaultInstance; + + /// Operator handle recorded in the chain.reset marker so the + /// discontinuity is attributable. Required. + @$pb.TagNumber(1) + $core.String get reviewer => $_getSZ(0); + @$pb.TagNumber(1) + set reviewer($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasReviewer() => $_has(0); + @$pb.TagNumber(1) + void clearReviewer() => $_clearField(1); + + /// Free-form reason recorded in the chain.reset marker. Required — + /// dropping audit events without a reason is the kind of action + /// operators are asked to defend later. + @$pb.TagNumber(2) + $core.String get reason => $_getSZ(1); + @$pb.TagNumber(2) + set reason($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasReason() => $_has(1); + @$pb.TagNumber(2) + void clearReason() => $_clearField(2); +} + +class ClearEventLogResponse extends $pb.GeneratedMessage { + factory ClearEventLogResponse({ + $fixnum.Int64? purged, + $core.String? channel, + }) { + final $result = create(); + if (purged != null) { + $result.purged = purged; + } + if (channel != null) { + $result.channel = channel; + } + return $result; + } + ClearEventLogResponse._() : super(); + factory ClearEventLogResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory ClearEventLogResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'ClearEventLogResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..a<$fixnum.Int64>(1, _omitFieldNames ? '' : 'purged', $pb.PbFieldType.OU6, defaultOrMaker: $fixnum.Int64.ZERO) + ..aOS(2, _omitFieldNames ? '' : 'channel') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ClearEventLogResponse clone() => ClearEventLogResponse()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ClearEventLogResponse copyWith(void Function(ClearEventLogResponse) updates) => super.copyWith((message) => updates(message as ClearEventLogResponse)) as ClearEventLogResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ClearEventLogResponse create() => ClearEventLogResponse._(); + ClearEventLogResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static ClearEventLogResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static ClearEventLogResponse? _defaultInstance; + + /// Number of events that were purged (excludes the new + /// chain.reset marker that seeds the fresh chain). + @$pb.TagNumber(1) + $fixnum.Int64 get purged => $_getI64(0); + @$pb.TagNumber(1) + set purged($fixnum.Int64 v) { $_setInt64(0, v); } + @$pb.TagNumber(1) + $core.bool hasPurged() => $_has(0); + @$pb.TagNumber(1) + void clearPurged() => $_clearField(1); + + /// Channel the operation ran on, echoed back so the CLI can + /// confirm which environment was affected. + @$pb.TagNumber(2) + $core.String get channel => $_getSZ(1); + @$pb.TagNumber(2) + set channel($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasChannel() => $_has(1); + @$pb.TagNumber(2) + void clearChannel() => $_clearField(2); +} + const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index 2ee5304..4f9bb72 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -175,6 +175,10 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/VerifyEventChain', ($1.Empty value) => value.writeToBuffer(), ($core.List<$core.int> value) => $0.VerifyEventChainResponse.fromBuffer(value)); + static final _$clearEventLog = $grpc.ClientMethod<$0.ClearEventLogRequest, $0.ClearEventLogResponse>( + '/fai.v1.HubAdmin/ClearEventLog', + ($0.ClearEventLogRequest value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.ClearEventLogResponse.fromBuffer(value)); static final _$listServices = $grpc.ClientMethod<$1.Empty, $0.ServiceList>( '/fai.v1.HubAdmin/ListServices', ($1.Empty value) => value.writeToBuffer(), @@ -292,6 +296,14 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$verifyEventChain, request, options: options); } + /// Wipe every audit event and seed the log with a single + /// `chain.reset` marker. Refused on `beta` / `production` for + /// compliance — only callable on `local` / `dev`. Surfaced by + /// the CLI as `fai admin events clear`. + $grpc.ResponseFuture<$0.ClearEventLogResponse> clearEventLog($0.ClearEventLogRequest request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$clearEventLog, request, options: options); + } + /// List host services declared in the operator config. Each /// entry carries name + endpoint; reachability is operator-side /// (on-demand `fai service status` or Studio probe). @@ -477,6 +489,13 @@ abstract class HubAdminServiceBase extends $grpc.Service { false, ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), ($0.VerifyEventChainResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$0.ClearEventLogRequest, $0.ClearEventLogResponse>( + 'ClearEventLog', + clearEventLog_Pre, + false, + false, + ($core.List<$core.int> value) => $0.ClearEventLogRequest.fromBuffer(value), + ($0.ClearEventLogResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$1.Empty, $0.ServiceList>( 'ListServices', listServices_Pre, @@ -608,6 +627,10 @@ abstract class HubAdminServiceBase extends $grpc.Service { return verifyEventChain($call, await $request); } + $async.Future<$0.ClearEventLogResponse> clearEventLog_Pre($grpc.ServiceCall $call, $async.Future<$0.ClearEventLogRequest> $request) async { + return clearEventLog($call, await $request); + } + $async.Future<$0.ServiceList> listServices_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { return listServices($call, await $request); } @@ -665,6 +688,7 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.ApprovalList> listApprovals($grpc.ServiceCall call, $0.ListApprovalsRequest request); $async.Future<$0.DecideApprovalResponse> decideApproval($grpc.ServiceCall call, $0.DecideApprovalRequest request); $async.Future<$0.VerifyEventChainResponse> verifyEventChain($grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.ClearEventLogResponse> clearEventLog($grpc.ServiceCall call, $0.ClearEventLogRequest request); $async.Future<$0.ServiceList> listServices($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.CheckUpdateResponse> checkUpdate($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.ChannelStatusResponse> channelStatus($grpc.ServiceCall call, $1.Empty request); diff --git a/lib/src/generated/fai/v1/hub.pbjson.dart b/lib/src/generated/fai/v1/hub.pbjson.dart index fd7af4a..a0ad60d 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -874,3 +874,31 @@ final $typed_data.Uint8List curatedModelDescriptor = $convert.base64Decode( '1SCGNvbnRleHRLEhQKBW5vdGVzGAcgASgJUgVub3RlcxIYCgdsaWNlbnNlGAggASgJUgdsaWNl' 'bnNl'); +@$core.Deprecated('Use clearEventLogRequestDescriptor instead') +const ClearEventLogRequest$json = { + '1': 'ClearEventLogRequest', + '2': [ + {'1': 'reviewer', '3': 1, '4': 1, '5': 9, '10': 'reviewer'}, + {'1': 'reason', '3': 2, '4': 1, '5': 9, '10': 'reason'}, + ], +}; + +/// Descriptor for `ClearEventLogRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List clearEventLogRequestDescriptor = $convert.base64Decode( + 'ChRDbGVhckV2ZW50TG9nUmVxdWVzdBIaCghyZXZpZXdlchgBIAEoCVIIcmV2aWV3ZXISFgoGcm' + 'Vhc29uGAIgASgJUgZyZWFzb24='); + +@$core.Deprecated('Use clearEventLogResponseDescriptor instead') +const ClearEventLogResponse$json = { + '1': 'ClearEventLogResponse', + '2': [ + {'1': 'purged', '3': 1, '4': 1, '5': 4, '10': 'purged'}, + {'1': 'channel', '3': 2, '4': 1, '5': 9, '10': 'channel'}, + ], +}; + +/// Descriptor for `ClearEventLogResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List clearEventLogResponseDescriptor = $convert.base64Decode( + 'ChVDbGVhckV2ZW50TG9nUmVzcG9uc2USFgoGcHVyZ2VkGAEgASgEUgZwdXJnZWQSGAoHY2hhbm' + '5lbBgCIAEoCVIHY2hhbm5lbA=='); + diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index 52cd099..927692d 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -53,6 +53,7 @@ typedef HardwareInfoResponse = pb.HardwareInfoResponse; typedef ListSystemAiCuratedModelsResponse = pb.ListSystemAiCuratedModelsResponse; typedef CuratedModel = pb.CuratedModel; +typedef ClearEventLogResponse = pb.ClearEventLogResponse; typedef ModuleInfoResponse = pb.ModuleInfoResponse; typedef FlowSummary = pb.FlowSummary; typedef StoreEntry = pb.StoreEntry; @@ -170,6 +171,20 @@ class HubClient { return _admin.verifyEventChain(Empty()); } + /// Wipe every audit event and seed a fresh `chain.reset` + /// marker carrying [reviewer] + [reason]. The hub refuses on + /// `beta` / `production` channels; on `local` / `dev` it + /// returns the count of events that were purged. + Future clearEventLog({ + required String reviewer, + required String reason, + }) { + return _admin.clearEventLog(pb.ClearEventLogRequest( + reviewer: reviewer, + reason: reason, + )); + } + /// Host services declared in the operator config. Each entry /// is a name + endpoint + tags; reachability is up to the /// caller (typically a follow-up HTTP probe). diff --git a/pubspec.yaml b/pubspec.yaml index 033bc16..028cfa3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: fai_dart_sdk description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps. -version: 0.7.0 +version: 0.7.1 publish_to: 'none' repository: https://git.flemming.ws/fai/dart-sdk