aiur-cli-linux-arm64 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentBuildGuard.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentChat.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentCommandInstaller.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentContextPresentation.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentControlCLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentEnvironment.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentEvents.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentGitHubGuard.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentList.Renderer.Chrome.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentList.Renderer.Layout.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentList.Renderer.Table.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentQueueItem.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentQueueStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.CheckpointDelivery.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.CommentContext.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.MessageHandler.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.ModelLabelRefresh.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.QueueDrain.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.SessionLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.ToolExecutor.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.TurnAlerts.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.TurnCallbacks.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.TurnProgress.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.TurnPrompt.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentRunner.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentSkills.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentTools.Catalog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentTools.MCP.Router.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AgentTools.MCP.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AlertFeed.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AlertLedger.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Alerts.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AppServer.Adapter.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AppServer.Messages.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AppServer.Rpc.StreamDiagnostics.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AppServer.Rpc.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.AppServer.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Application.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.Cadence.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.CatalogStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Queries.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Reconciliation.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Configuration.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Options.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Policy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.GraphProjection.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.ProgressRenderer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Repository.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.BuildOrdersCLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CIApprovalStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.NotificationPolicy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.Repl.Launcher.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.Repl.Reaper.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.ResetTime.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.Telemetry.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Claude.UsageApi.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.AccountGeneration.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.DynamicTool.Errors.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.DynamicTool.TicketState.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.DynamicTool.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.ExhaustedReset.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.NotificationPolicy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.Notifications.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.ResetTime.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Codex.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.ModelLabel.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Models.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Providers.Claude.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Providers.Codex.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Providers.Fake.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Providers.Muse.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.Registry.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Paths.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Agent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.BuildOrder.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Claude.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Codex.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Github.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Linear.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.MuseBackend.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Rtk.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.Schema.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Config.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.CurrentRunMembership.Reconciler.Snapshot.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Decision.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionApi.PublicLifecycleProjection.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionAttentionSignals.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionDispatch.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionEvent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionHistory.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionProjection.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionPubSub.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionSanitizer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.DecisionStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Env.Schema.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Env.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.EventPublicationLog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubCommentsPoller.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubKeys.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubReviewThreadIdentity.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubWebhook.Deposit.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubWebhook.Normalizer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.GithubWebhook.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.IdGenerator.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.PrCommandScanner.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.Publisher.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.Sanitizer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Events.SubscriptionStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Executor.Claims.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Executor.Principal.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ExecutorCommandCLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ExecutorWakeInbox.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.AgentMarker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.AuthPreflight.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.BoundedBlockedBy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.BrokerTimeout.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Budget.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.BudgetLedger.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.CiReadiness.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Client.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.CommentPollBatch.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Comments.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Config.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Credential.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.CredentialSelector.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.DependenciesApi.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.DispatchAuthorization.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Issues.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Labels.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.LocalHold.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.OpenIssueSnapshot.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.PullRequests.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.ReadCache.Metrics.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.ReadCache.Policy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.ReadCache.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.ResourceEvents.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.ResourceStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHub.WriteThrough.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GitHubCostCLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.GlobalConfigStartup.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.AgentCli.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.BackendConfigs.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.BotAccount.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.GitHub.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.GitHubApp.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.Labels.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.Questions.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.Templates.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Init.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.IssueLog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.LaunchStateAdoption.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.LauncherWatchdog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Linear.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Memory.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ModelAvailability.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ModelCatalog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ModelDiscovery.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Approvals.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Defaults.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.EventNormalizer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Init.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.MeterProbe.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Meters.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.ModelCatalog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Protocol.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Session.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.SessionRecovery.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Transcript.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Transport.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Turn.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.TurnControl.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.Usage.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Muse.View.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.OpenAICompat.CommandRunner.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.OpenAICompat.ProviderMeterProbe.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.DeltaRenderer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.InputIdentity.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.OperatorDispatch.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.TurnRequest.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.TurnStream.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.ChatCompletions.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.Slot.ServeLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Opencode.WorkspaceSetup.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.AutoSubscriptions.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.CapacityBinding.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.CiLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.CommentPolling.TargetSelection.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.CommentPolling.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.CommentWake.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.ControlLifecycleStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.DispatchPolicy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.Dispatcher.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.EventTopics.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.IssueSync.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.Lifecycle.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.LifecycleFence.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.OperatorMessages.DeliveryPolicy.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.OperatorMessages.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.OrphanedWorkers.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.PauseResume.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.RateLimitFallback.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.ReadyForReviewTransitions.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.RetryEngine.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.ReworkGate.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.State.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.StatusReason.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.StatusReport.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.TokenAccounting.Payloads.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.TokenAccounting.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.TrackerHealth.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.WaitingReason.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.WorkspaceCleanup.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Orchestrator.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.PrReadyLedgerStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.PromptBuilder.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeterProbe.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeterProjection.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeterSnapshot.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeters.CLI.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeters.HostObservations.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeters.HostSnapshot.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeters.Input.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.ProviderMeters.Text.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.PubSub.Boot.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.RecentMerge.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Rtk.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.RunTelemetry.Dataset.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.RunTelemetry.Procfs.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.RunTelemetry.Writer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.SessionHandle.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Shutdown.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.TestReset.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.TestShard.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Usage.Headless.Muse.SessionUsage.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Usage.PriceTable.Validator.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.UsageAggregate.Key.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.UsageEnvelope.RelationshipRegistry.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.UsageEnvelope.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Webhooks.DeliveryModeEvents.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Webhooks.EventKey.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Webhooks.ModeRegistry.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Webhooks.ModeTable.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workflow.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.WorkflowStore.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Checkout.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.HostLock.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Layout.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Materialize.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Ownership.Guardian.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Ownership.Store.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Ownership.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Provisioner.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.Refresh.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Workspace.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Aiur.Yaml.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.AnalyticsLive.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.BuildOrder.DataSource.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.BuildOrder.PlanningSource.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.BuildOrder.SourceRuntime.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.BuildOrderLive.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.BuildOrderPresenter.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.DashboardLive.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.Endpoint.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.FinancialData.ChangeBridge.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.FinancialDataAccess.Proof.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.GithubWebhookController.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.ObservabilityApiController.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.AddAgentModal.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.AddAgentSubmission.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.AgentLogModal.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.AgentRoutingPreview.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.Styles.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderAnalytics.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderBreakdown.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderCatalog.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderGraph.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderGridModel.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderSelected.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderStatus.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderTicketContext.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.ConversationDrawer.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.CurrentRunOutcomes.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DashboardShell.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionAction.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionCard.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionDetail.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionInbox.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionLatency.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionRevisionAction.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.FleetTable.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.History.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.LifecycleComponents.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.Money.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.Overview.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.ProviderMeters.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.ProviderMetersPresenter.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.RecentOutcomes.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.RouteRegistry.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.RunSummaryStrip.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketContext.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketDetailModal.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketsPanel.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsFilters.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsPresentation.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsTable.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.UsageSummary.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.OperatorControlCenter.UsageSummaryPresenter.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.Presenter.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.Router.Helpers.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.Router.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.StaticAssets.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.StreamdeckChannel.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.StreamdeckLive.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.AiurWeb.StreamdeckStrip.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/Elixir.Mix.Tasks.Aiur.TestShard.beam +0 -0
- package/release/lib/aiur-0.0.6/ebin/aiur.app +1051 -0
- package/release/lib/aiur-0.0.6/priv/build_gate.bash +1912 -0
- package/release/lib/aiur-0.0.6/priv/build_gate_command_wrapper.bash +292 -0
- package/release/lib/aiur-0.0.6/priv/github_budget.py +919 -0
- package/release/lib/aiur-0.0.6/priv/github_quota_guard.sh +3403 -0
- package/release/lib/aiur-0.0.6/priv/opencode_plugins/input-identity.mjs +37 -0
- package/release/lib/aiur-0.0.6/priv/static/dashboard.css +10292 -0
- package/release/lib/aiur-0.0.6/priv/static/muse.svg +6 -0
- package/release/lib/bandit-1.12.4/ebin/Elixir.Bandit.beam +0 -0
- package/release/lib/decimal-3.1.1/ebin/Elixir.Decimal.beam +0 -0
- package/release/lib/mint-1.9.3/ebin/Elixir.Mint.HTTP2.Frame.beam +0 -0
- package/release/lib/phoenix_live_view-1.1.33/ebin/Elixir.Phoenix.Component.beam +0 -0
- package/release/lib/tz-0.28.2/ebin/Elixir.Tz.PeriodsProvider.beam +0 -0
- package/release/releases/0.0.6/aiur.rel +49 -0
- package/release/releases/0.0.6/start.boot +0 -0
- package/release/releases/0.0.6/start.script +4743 -0
- package/release/releases/0.0.6/start_clean.boot +0 -0
- package/release/releases/0.0.6/start_clean.script +4700 -0
- package/release/releases/COOKIE +1 -1
- package/release/releases/start_erl.data +1 -1
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentBuildGuard.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentChat.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentCommandInstaller.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentControlCLI.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentEnvironment.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentEvents.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentGitHubGuard.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentList.Renderer.Chrome.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentList.Renderer.Layout.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentList.Renderer.Table.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentQueueItem.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentQueueStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.CheckpointDelivery.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.CommentContext.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.MessageHandler.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.QueueDrain.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.SessionLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.ToolExecutor.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.TurnAlerts.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.TurnCallbacks.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.TurnPrompt.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentRunner.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AgentSkills.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AlertFeed.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AlertLedger.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Alerts.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AppServer.Adapter.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AppServer.Messages.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AppServer.Rpc.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.AppServer.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Application.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.Cadence.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Queries.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Configuration.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Options.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Policy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GraphProjection.StoreCatalog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.GraphProjection.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.ProgressRenderer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Repository.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.BuildOrdersCLI.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.CIApprovalStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.CLI.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.NotificationPolicy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.Repl.Launcher.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.Repl.Reaper.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.Telemetry.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Claude.UsageApi.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.AccountGeneration.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.DynamicTool.Errors.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.DynamicTool.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.NotificationPolicy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.Notifications.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Codex.TurnLoop.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.CodingAgent.Models.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.CodingAgent.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Paths.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Agent.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.BuildOrder.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Claude.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Codex.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Github.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Linear.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.Schema.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Config.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.CurrentRunMembership.Reconciler.Snapshot.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Decision.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionApi.PublicLifecycleProjection.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionAttentionSignals.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionDispatch.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionEvent.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionHistory.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionProjection.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionPubSub.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionSanitizer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.DecisionStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Env.Schema.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Env.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.EventPublicationLog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.GithubCommentsPoller.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.GithubKeys.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.GithubWebhook.Deposit.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.GithubWebhook.Normalizer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.GithubWebhook.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.IdGenerator.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.PrCommandScanner.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.Publisher.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.Sanitizer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Events.SubscriptionStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Executor.Claims.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ExecutorCommandCLI.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ExecutorWakeInbox.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.AgentCacheMetrics.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.AuthPreflight.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Budget.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.BudgetLedger.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.BudgetMap.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheHistory.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.Entry.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.Events.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.Redactor.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.ResourceStoreSource.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.Source.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CacheInspector.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CiReadiness.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Client.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CommentPollBatch.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Comments.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Config.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Credential.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.CredentialSelector.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.DependenciesApi.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.DispatchAuthorization.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Issues.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Labels.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.LocalHold.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.PullRequests.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.QuotaHistory.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.QuotaUsage.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.ReadCache.Metrics.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.ReadCache.Policy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.ReadCache.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.ResourceEvents.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.ResourceStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHub.WriteThrough.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.GitHubCostCLI.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.AgentCli.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.BotAccount.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.GitHub.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.Labels.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.Questions.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.Templates.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Init.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.IssueLog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.LauncherWatchdog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Linear.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Memory.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ModelAvailability.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ModelCatalog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ModelDiscovery.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.OpenAICompat.CommandRunner.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.OpenAICompat.ProviderMeterProbe.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.ChatCompletions.DeltaRenderer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.ChatCompletions.OperatorDispatch.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.ChatCompletions.TurnRequest.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.ChatCompletions.TurnStream.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.ChatCompletions.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.Slot.ServeLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Opencode.WorkspaceSetup.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.AutoSubscriptions.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.CapacityBinding.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.CiLifecycle.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.CommentPolling.TargetSelection.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.CommentPolling.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.CommentWake.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.ControlLifecycleStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.DispatchPolicy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.Dispatcher.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.EventTopics.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.IssueSync.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.Lifecycle.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.LifecycleFence.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.OperatorMessages.DeliveryPolicy.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.OperatorMessages.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.PauseResume.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.RateLimitFallback.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.RetryEngine.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.ReworkGate.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.State.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.StatusReason.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.StatusReport.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.TokenAccounting.Payloads.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.TokenAccounting.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.TrackerHealth.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.WaitingReason.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.WorkspaceCleanup.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Orchestrator.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.PromptBuilder.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ProviderMeterProbe.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ProviderMeterProjection.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ProviderMeterSnapshot.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.ProviderMeters.Input.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.RecentMerge.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.RunTelemetry.Dataset.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.RunTelemetry.Procfs.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.RunTelemetry.Writer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.SessionHandle.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Shutdown.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.TestReset.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Tracker.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Usage.PriceTable.Validator.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.UsageAggregate.Key.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.UsageEnvelope.RelationshipRegistry.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.UsageEnvelope.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Webhooks.EventKey.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Webhooks.ModeRegistry.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Webhooks.ModeTable.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workflow.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.WorkflowStore.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Checkout.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Layout.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Materialize.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Ownership.Guardian.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Ownership.Store.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Ownership.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Provisioner.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.Refresh.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.Aiur.Workspace.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.AnalyticsLive.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.BuildOrder.DataSource.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.BuildOrder.PlanningSource.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.BuildOrder.SourceRuntime.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.BuildOrderLive.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.BuildOrderPresenter.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.DashboardLive.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.Endpoint.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.FinancialData.ChangeBridge.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.FinancialDataAccess.Proof.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.GithubCacheLive.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.GithubWebhookController.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.ObservabilityApiController.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.AddAgentModal.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.AgentLogModal.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.AgentRoutingPreview.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.Styles.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderAnalytics.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderBreakdown.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderCatalog.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderGraph.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderGridModel.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderSelected.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderStatus.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderTicketContext.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.ConversationDrawer.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.CurrentRunOutcomes.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DashboardShell.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionAction.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionCard.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionDetail.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionInbox.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionLatency.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionRevisionAction.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.FleetTable.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.GithubCache.Charts.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.GithubCache.Styles.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.History.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.LifecycleComponents.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.Overview.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.ProviderMeters.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.ProviderMetersPresenter.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.RecentOutcomes.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.RouteRegistry.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.RunSummaryStrip.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketContext.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketDetailModal.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketsPanel.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsFilters.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsPresentation.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsTable.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.UsageSummary.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.OperatorControlCenter.UsageSummaryPresenter.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.Presenter.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.Router.Helpers.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.Router.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.StaticAssets.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.StreamdeckChannel.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.StreamdeckLive.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/Elixir.AiurWeb.StreamdeckStrip.beam +0 -0
- package/release/lib/aiur-0.0.5/ebin/aiur.app +0 -1006
- package/release/lib/aiur-0.0.5/priv/build_gate.bash +0 -1874
- package/release/lib/aiur-0.0.5/priv/build_gate_command_wrapper.bash +0 -214
- package/release/lib/aiur-0.0.5/priv/github_budget.py +0 -898
- package/release/lib/aiur-0.0.5/priv/github_quota_guard.sh +0 -3233
- package/release/lib/aiur-0.0.5/priv/static/dashboard.css +0 -10159
- package/release/releases/0.0.5/aiur.rel +0 -49
- package/release/releases/0.0.5/start.boot +0 -0
- package/release/releases/0.0.5/start.script +0 -4660
- package/release/releases/0.0.5/start_clean.boot +0 -0
- package/release/releases/0.0.5/start_clean.script +0 -4617
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AffectedTests.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentConfig.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentDirectory.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentEventFeed.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentEventLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Activation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.ActivityIntake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.App.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Controls.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.EventIntake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Input.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.PerfIntake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.RcPaneBorders.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.RenderState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Cells.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.EventLine.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.EventPhrases.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.EventsBlock.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Help.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Links.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Markers.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Model.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Style.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.Text.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Renderer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Roster.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Selection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.Summaries.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentList.WarmthIntake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentProcessLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentPubSub.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentQueue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentResourceGuard.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentRunner.BootstrapDigest.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentRunner.CodexUpdateRelay.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentRunner.EventsDigest.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentRunner.SessionResume.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentRunner.TurnStreams.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AgentScratch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AlertFeed.Backfill.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AlertLedger.Tail.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AlertTopic.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AnalyticsCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.InterruptHandshake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.Interrupts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.OperatorDelivery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.ProviderTurnLedger.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.Rpc.Await.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.Rpc.SensitiveResponses.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.Rpc.Stream.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.ToolCallIdentity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.ToolCallLedger.Storage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.ToolCallLedger.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.ToolResultSpill.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AppServer.TurnState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Asks.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Asks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.AsksCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Boot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildGate.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildGateHoldMonitor.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildGateHoldMonitor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Activity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.AdHocSource.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.AdHocSource.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Bounded.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Catalog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Dependency.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.DependencyChain.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Diagnostic.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.EdgeState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Connection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Dependencies.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Endpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Normalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Pager.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Request.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Result.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Settings.Paging.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.Settings.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GitHubGraph.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Graph.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GraphAnalysis.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Failure.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GraphProjection.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.GraphProjection.TaskLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Icon.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Lifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Marker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Member.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Metadata.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.PackPaths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.PackStatus.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.ProviderHealth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.ProviderResult.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.Readiness.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.RootSummary.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.SelectedRoot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.DestinationNormalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Destinations.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Failure.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.IssueDestination.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Normalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.PullRequestDestination.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Sanitizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetail.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetailCoordinator.Configuration.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetailCoordinator.Options.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetailCoordinator.Policy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetailCoordinator.TaskLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketDetailCoordinator.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistory.Entry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistory.Failure.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistory.Normalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistory.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistoryProvider.Options.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.BuildOrder.TicketHistoryProvider.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.AccountGeneration.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.AccountGeneration.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.AccountMeters.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.DisplayTailer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.EventHumanizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.HookEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.HookSettings.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.RateLimitAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.RemoteControl.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.Command.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.HookTurn.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.OperatorInject.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.PromptSubmit.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.RcAttach.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.TranscriptTurn.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Repl.TurnEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.ReplAgent.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.Contract.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.Event.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.Receiver.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.UsageAdapter.Relationship.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.UsageAdapter.Validation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Telemetry.UsageAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.Transcript.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Claude.TranscriptTailer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codeowners.Edit.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codeowners.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.AccountGeneration.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.AppServerPort.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Approvals.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.Args.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.Blockers.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.EmitAlert.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.EmitEvent.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.Handler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.LinearGraphQL.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.Response.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.ReviewThreads.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.DynamicTool.Subscriptions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.EventHumanizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.EventNormalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Frames.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Handshake.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Interrupts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.OperatorDelivery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.RateLimitAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.RateLimits.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Rpc.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.SessionLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.SessionRecovery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.Transcript.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.TurnEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Codex.UserInputAnswers.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CodingAgent.Backend.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CodingAgent.RouteCredentials.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CodingAgent.RouteFailure.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CommandsCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.CodexSandboxPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.EnvRef.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.RoutingValue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.AgentValidation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Alerts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Attrs.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Decisions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.ElevenLabs.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.EnvResolver.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Errors.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Events.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.GithubApp.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.GithubCredential.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Hooks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Observability.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Opencode.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Polling.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.PrHealth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.PrWatch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Prewarm.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.PricingPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Server.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.StringOrMap.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Upgrade.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Webhooks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Worker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Config.Schema.Workspace.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Conversations.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CoordinationTasks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Event.Codec.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Event.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Projection.Member.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Reconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.Checkpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.FileOps.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.Marker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.Paths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.Recovery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.Runtime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.TerminalVerification.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunMembership.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunOutcomeSnapshot.MembershipIndex.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunOutcomeSnapshot.Outcomes.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunOutcomeSnapshot.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunOutcomeSnapshot.SourceState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunOutcomeSnapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjection.Value.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.Checkpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.CheckpointPersistence.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.Finalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.MembershipCache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.Projector.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.Refresh.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.SourceAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.SourceCollector.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.SourceFallback.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.UnitsBuilder.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.WeightFacts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunProjections.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunSummary.Facts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunSummary.Progress.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunSummary.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunSummary.Status.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.CurrentRunSummary.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DaemonLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionAnswer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionApi.LegacyPagination.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionApi.PublicProjection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionApi.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionArtifact.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionAttention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionAuthority.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionCommandType.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDelegation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDispatchTasks.Owner.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDispatchTasks.Queue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDispatchTasks.Saturation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDispatchTasks.Worker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionDispatchTasks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionEnrichment.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionEvent.Unrecognized.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionExpiry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Bootstrap.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Canonical.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Collector.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Event.Fields.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Event.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Log.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Options.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Sample.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Window.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Writer.Persistence.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.Writer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionMetrics.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionProvenance.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionQuery.Cursor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionQuery.Params.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionQuery.StoreReader.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionQuery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionRevision.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionRevisionDispatch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionStore.RetainedIndex.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionStore.RetainedSnapshot.LegacyPage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionStore.RetainedSnapshot.Query.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionStore.RetainedSnapshot.QueryPlan.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionStore.RetainedSnapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DecisionValidation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.DispatchBudgetStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Distribution.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.Quota.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.Realtime.MintSocket.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.Realtime.MintTransport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.Realtime.Transport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.Realtime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ElevenLabs.TTS.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Env.Types.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.EventHumanizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.EventHumanizerHelpers.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.AgentSubscriptionPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.BranchRefStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.CommentFilter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.DebugLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.Exchange.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.GithubCIPoller.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.GithubFirehose.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.GithubWebhook.ThreadResolver.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.LsRemoteTicker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.SubscriptionStoreSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.Topic.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Events.UniversalSubscriptions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.Handoff.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.Roster.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.StatePaths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.TakeoverAlert.Monitor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.TakeoverAlert.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.TakeoverAlert.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Executor.TakeoverAlert.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExecutorBindings.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExecutorCommandAttention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExecutorEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExecutorListener.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExecutorWakeProjection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ExternalContent.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Findings.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.FindingsCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Fs.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Git.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.AgentCache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.AgentCacheBridge.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.AppCredentials.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.AppToken.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.AppTokenRefresher.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.BotIdentity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CIPollBatch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CodeOwners.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.Connectivity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CredentialHeadroom.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CredentialRegistry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CredentialUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.CycleFetchCache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.DeliveredPullRequest.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.EndpointPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.Errors.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.GraphQLCost.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.GraphQLErrors.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.HostCommand.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.HumanReviewGate.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.IssueDependencies.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.IssueRelationships.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.IssueState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.MergeQueue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.PollSnapshots.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.Quota.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ReadCache.Identity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.RepoEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.RequestLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.RequestOrigin.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ResourceFetch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ReviewThreads.Reply.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ReviewThreads.Resolution.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ReviewThreads.ResolutionPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ReviewThreads.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.StatePolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.Teams.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.Transport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ViewStateDemand.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHub.ViewStateSweep.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.GitHubUsageCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.HttpServer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Alerts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Codeowners.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Dotenv.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.ElevenLabs.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Format.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Prewarm.Failure.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Prewarm.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Prompt.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Resume.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Runtime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Init.Scaffold.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Issue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.IssueContext.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.JSONSafe.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.JsonStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Jsonl.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Linear.Client.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Linear.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LiveConversation.Compactor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LiveConversation.Normalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LiveConversation.Retention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LiveConversation.Source.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LiveConversation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.LogFile.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Logs.Retention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Memory.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Metrics.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ModelDiscovery.Source.Anthropic.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ModelDiscovery.Source.OpenAI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ModelDiscovery.Source.OpenRouter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ModelDiscovery.Source.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpaqueIdentifier.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.AccountGeneration.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.BalanceBaseline.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.BoundedGlob.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Checkpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.CodingAgent.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Concurrency.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Conversation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.MeterAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.MeterWindows.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Registry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Session.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.ToolCallParser.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.ToolSpec.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Tools.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Transcript.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.Transport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenAICompat.WorkspacePath.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenTicketSource.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpenTicketSource.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ActiveTurns.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ApiClient.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.AttachPool.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Bridge.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.BridgePort.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.BridgeSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ChatCompletions.Caller.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ChatCompletions.Replay.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ChatCompletions.Sse.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.ChatCompletions.StreamPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Config.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Db.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.EventConsumer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.EventRow.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.HiddenWindow.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.OperatorText.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.PaneSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.PrewarmSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Protocol.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Server.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SessionGC.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SessionSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SessionWriter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SessionWriterRegistry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Slot.AttachPane.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Slot.Events.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Slot.Sessions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Slot.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Slot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SlotPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SlotRegistry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.SlotSupervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.Style.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.TokenRegistry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.TurnMarkers.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Opencode.WarmthReport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OpencodeTheme.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.OperatorWaitLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.AgentTeardown.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.AutoResume.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.CommandScan.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.ControlLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.DigestCoalescer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.GithubBudgetPause.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.GlobalPause.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.GlobalPauseStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.HumanReview.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.Interrupts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.MembershipLifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.MergedTicketReconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.OperatorMessages.Capabilities.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.PRHealthScanner.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.PrAnchored.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.PriorityControl.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.PushRouting.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.Reconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.RemoteControlMode.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.ReviewFreshness.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.ReworkRequeue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.RuntimeWatchdog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.Slots.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.SnapshotPublisher.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.SnapshotStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.StartupClaimReconciler.BootMarker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.StartupClaimReconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Orchestrator.TrackedSet.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Os.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.Anchor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.Close.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.ConvoPaint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.GenericOpen.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.Layout.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.OpenQueue.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.OpencodeOpen.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.Placeholder.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.Reconcile.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.ScreenGrab.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.SlotAttach.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PaneManager.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PathSafety.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PauseContainment.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Perf.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PeriodicWorker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.PollCadence.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Prewarm.Detect.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProcessIdentity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProcessReaper.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProgressCheckin.Worker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProgressRetention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProgressTracker.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Protocol.MapAccess.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Continuity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Events.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Lifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Monitor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Owner.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Registry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Snapshot.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Tombstones.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.Validation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderAccountGeneration.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeterRefresh.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeters.Events.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeters.ProbeCrash.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeters.Reconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeters.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.ProviderMeters.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RecentMergeStore.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RepoBase.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Dashboard.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.GitHubEnricher.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Lifecycle.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Retention.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Sampler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Summaries.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Supervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.Timeline.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.RunTelemetry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SSH.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Sandbox.EventFlowDemo.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Sandbox.EventFlowUnrelated1.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Sandbox.EventFlowUnrelated2.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Sandbox.EventFlowUnrelated3.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SaturationSentinel.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SaturationSentinel.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SecretRedactor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Shell.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SpecsCheck.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SupervisionHealth.Formatter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SupervisionHealth.Tree.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SupervisionHealth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SupervisorToken.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SystemCpu.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SystemFileDescriptors.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SystemLoad.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.SystemMemory.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TicketActivity.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TicketActivity.Reducer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TicketActivity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TicketBranch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TicketObservation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Exec.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Input.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Layout.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.MockTransport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Protocol.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Query.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.Style.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Tmux.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TokenUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TrackerConfig.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.TrackerIdentity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UnitsCLI.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.Notice.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.Registry.Transport.Req.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.Registry.Transport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.Registry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.Version.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Upgrade.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.GroupedScopes.PriceAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.GroupedScopes.Scope.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.GroupedScopes.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Adapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Catalog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Claude.RequestUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Codex.ThreadUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Codex.Tokens.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Codex.TurnUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Compatibility.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.DeepSeek.RequestUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Emitter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Kimi.RequestUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.Normalizer.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.OpenAICompat.RequestUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Headless.OpenRouter.RequestUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.PriceTable.Data.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.PriceTable.ProviderDimensions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.PriceTable.Window.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.PriceTable.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Pricing.Components.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Pricing.Dimensions.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Pricing.Result.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Usage.Pricing.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Checkpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Paths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Query.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Recovery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageAggregate.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Block.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Coordinator.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Floor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Manifest.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Paths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageCompaction.Policy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageEnvelope.Codec.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageEnvelope.ExactMoney.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.Checkpoint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.CounterPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.Paths.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.Record.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.Recovery.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.RetiredFloor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.Store.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.UsageLedger.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.DeliveryLog.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.DeliveryMode.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.EventSource.Polling.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.EventSource.Webhook.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.EventSource.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.Ingest.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.IntervalPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.LabelState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.ModePresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Webhooks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.WorkflowStore.Cache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.WorkflowStore.State.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.BootstrapImage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.GitMetadata.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Hooks.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Ownership.Reconciler.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Ownership.Waiter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Reconstruction.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Remote.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.Workspace.Remove.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Aiur.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.AnalyticsRuntime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.AnalyticsScope.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.ContextRuntime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.RouteState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.Runtime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextAdapter.Relationship.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextAdapter.View.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextAdapter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextPresenter.Capability.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextPresenter.LogEntry.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextPresenter.View.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.TicketContextSelection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.UsageRuntime.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrder.UsageScope.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.Capability.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.Edge.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.Group.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.Node.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.Relationships.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.BuildOrderViewModel.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.CommandsRedirectController.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.ControlCenterCache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.ControlCenterPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.DecisionApiController.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.ErrorHTML.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.ErrorJSON.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialData.Cache.Pending.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialData.Cache.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialData.SubscriptionAuthority.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialData.Supervisor.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialData.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialDataAccess.Context.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialDataAccess.Generation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.FinancialDataAccess.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.GithubWebhook.Auth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.GithubWebhook.BodyReader.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.GithubWebhook.Signature.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.GithubWebhook.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.Layouts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.Markdown.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.ObservabilityPubSub.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.Charts.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.LatestRun.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.Presenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.Analytics.ScopeResolver.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.AwaitingCommands.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderEpicIcon.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderIcon.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.BuildOrderUsage.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.CapacityControl.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.CapacityPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.ConversationDrawer.Presenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.CurrentRunOutcomesPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionCommands.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionEvents.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionPath.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.DecisionProvider.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.FleetFilters.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.NavState.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.PayloadLoader.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.ProviderMeterSource.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.RevisionCommands.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.RowToken.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.RunSummary.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.RunSummaryPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketSearch.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.TicketsPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.TimeFormat.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsControlPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsPolicy.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsPresenter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.Fields.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.Projection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.ResumeReason.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.Sources.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.URL.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.Value.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsRow.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.OperatorControlCenter.UnitsURL.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StaticAssetController.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamDeckGrid.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckAuth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckCommands.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckKeyFaceContract.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckLogs.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckProjection.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckSessionController.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckSocket.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.StreamdeckTranscriptRelay.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.SupervisorAuth.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.VoiceChannel.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.VoiceSessionLimiter.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.AiurWeb.VoiceSocket.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Jason.Encoder.Aiur.TicketObservation.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Jason.Encoder.Aiur.TrackerIdentity.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.AffectedTests.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.CostReport.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.Env.Example.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.PricingWindow.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.Telemetry.Dashboard.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Aiur.Test.Reset.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Lint.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.PrBody.Check.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Specs.Check.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/ebin/Elixir.Mix.Tasks.Workspace.BeforeRemove.beam +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/build_gate_holder.py +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/build_orders/README.md +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/build_orders/aiur-build-order.json +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/build_orders/analytics-optimizations.json +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/build_orders/croptracker-demo.json +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/github_push_guard.sh +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/opencode_themes/aiur.json +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/pidfd_reap.py +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/interaction-policy.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/interaction.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/lifecycle.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/measurement.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/protocol.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout/renderer.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout-adapter.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-dom-svg-layout-loader.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/aiur-logo.png +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/build-order-grid-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/bungee.woff2 +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/claude-symbol.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/claude-token.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/codex-color.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/codex-token.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/conversation-drawer-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/conversation-voice-controller.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/deepseek-token.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/deepseek.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/elevenlabs-symbol.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/images/github-mark.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/kimi-token.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/kimi.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/openrouter-token.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/openrouter.svg +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/sortable-table-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/streamdeck-emulator-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/ticket-context-dialog-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/time-brush-hook.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/LICENSE.md +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/PROVENANCE.md +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/SOURCE.md +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/aiur-layout-client.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/aiur-layout-worker.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/elk-worker.min.js +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/vendor/elk/0.11.1/manifest.json +0 -0
- /package/release/lib/{aiur-0.0.5 → aiur-0.0.6}/priv/static/voice-capture-worklet.js +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Bandit.HTTPTransport.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Bandit.WebSocket.Socket.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Collectable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.DBConnection.Query.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Ecto.Queryable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Enumerable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.IEx.Info.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Inspect.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.JSON.Encoder.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Jason.Encoder.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.List.Chars.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Phoenix.HTML.FormData.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Phoenix.HTML.Safe.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Phoenix.Param.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Plug.Exception.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Solid.Block.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Solid.Matcher.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Solid.Renderable.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.String.Chars.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/consolidated/Elixir.Ymlr.Encoder.beam +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/elixir +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/env.sh +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/iex +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/remote.vm.args +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/sys.config +0 -0
- /package/release/releases/{0.0.5 → 0.0.6}/vm.args +0 -0
|
@@ -1,3233 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
# Fleet guard for agent-launched `gh` calls. The daemon prepends this wrapper's
|
|
4
|
-
# directory to agent PATH and supplies the real executable separately.
|
|
5
|
-
# #1793: a ticket filed without a dispatch disposition is undispatchable and
|
|
6
|
-
# invisible. The repo PreToolUse hook and the agent-suite tests invoke this
|
|
7
|
-
# wrapper in validate-only mode to check a `gh` issue command's disposition
|
|
8
|
-
# without requiring a real gh executable or touching any quota/budget state.
|
|
9
|
-
validate_only=0
|
|
10
|
-
if [ "${1:-}" = --validate-issue-command ]; then
|
|
11
|
-
validate_only=1
|
|
12
|
-
shift
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
dispatch_prefix=${AIUR_GITHUB_LABEL_PREFIX:-agent}
|
|
16
|
-
direct_issue_api=0
|
|
17
|
-
|
|
18
|
-
real_gh=${AIUR_REAL_GH:-}
|
|
19
|
-
is_guard_gh() {
|
|
20
|
-
case "$1" in
|
|
21
|
-
"$HOME/.aiur/bin/gh"|"$HOME/.aiur/github-budget/bin/gh"|*/.aiur-runtime/bin/gh) return 0 ;;
|
|
22
|
-
*) return 1 ;;
|
|
23
|
-
esac
|
|
24
|
-
}
|
|
25
|
-
if [ -n "$real_gh" ] && is_guard_gh "$real_gh"; then real_gh=; fi
|
|
26
|
-
if [ -z "$real_gh" ]; then
|
|
27
|
-
guard_dir=$(CDPATH= cd "$(dirname "$0")" && pwd)
|
|
28
|
-
guard_path=${PATH:-}
|
|
29
|
-
guard_old_ifs=$IFS
|
|
30
|
-
IFS=:
|
|
31
|
-
for guard_entry in $guard_path; do
|
|
32
|
-
[ -n "$guard_entry" ] || guard_entry=.
|
|
33
|
-
[ "$guard_entry" = "$guard_dir" ] && continue
|
|
34
|
-
guard_candidate=$guard_entry/gh
|
|
35
|
-
is_guard_gh "$guard_candidate" && continue
|
|
36
|
-
if [ -x "$guard_candidate" ]; then real_gh=$guard_candidate; break; fi
|
|
37
|
-
done
|
|
38
|
-
IFS=$guard_old_ifs
|
|
39
|
-
unset guard_dir guard_path guard_old_ifs guard_entry guard_candidate
|
|
40
|
-
fi
|
|
41
|
-
if [ "$validate_only" -eq 0 ] && { [ -z "$real_gh" ] || [ ! -x "$real_gh" ]; }; then
|
|
42
|
-
printf '%s\n' 'aiur: real gh executable is unavailable' >&2
|
|
43
|
-
exit 127
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
state_root=${AIUR_REPO_STATE_PATH:-}
|
|
47
|
-
quota_dir=
|
|
48
|
-
agent_quota_dir=${AIUR_AGENT_QUOTA_STATE_PATH:-}
|
|
49
|
-
events_file=
|
|
50
|
-
budget_root=${AIUR_GITHUB_BUDGET_ROOT:-"$HOME/.aiur/github-budget"}
|
|
51
|
-
budget_key=${AIUR_GITHUB_BUDGET_KEY:-}
|
|
52
|
-
budget_identity_key=${AIUR_GITHUB_BUDGET_IDENTITY_KEY:-}
|
|
53
|
-
budget_broker=${AIUR_GITHUB_BUDGET_BROKER:-"$(dirname "$0")/aiur-github-budget"}
|
|
54
|
-
budget_requested=${AIUR_GITHUB_BUDGET_ENABLED:-1}
|
|
55
|
-
budget_db=
|
|
56
|
-
budget_enabled=0
|
|
57
|
-
budget_required=0
|
|
58
|
-
budget_unavailable_reason=
|
|
59
|
-
budget_recovery="budget root $budget_root; repair ownership/permissions and redispatch (current runtimes derive this grant); stale runtimes must add $budget_root to agent.codex.turn_sandbox_policy.writableRoots"
|
|
60
|
-
budget_lease=
|
|
61
|
-
budget_renewal_pid=
|
|
62
|
-
budget_lease_ttl_ms=${AIUR_GITHUB_LEASE_TTL_MS:-35000}
|
|
63
|
-
budget_ignore_token_cooldown=0
|
|
64
|
-
# Seconds a failed identity derivation stays cached before the next admitted
|
|
65
|
-
# call retries it. Bounds an outage to one `gh api user` per credential per
|
|
66
|
-
# window instead of one per call (`budget_derive_identity`, #2353 review).
|
|
67
|
-
budget_identity_retry_ttl=300
|
|
68
|
-
budget_consumer=${AIUR_GITHUB_BUDGET_CONSUMER:-"executor:${PPID:-$$}"}
|
|
69
|
-
budget_consumer_key=
|
|
70
|
-
# Set when THIS wrapper resolved the credential key from a token rather than
|
|
71
|
-
# receiving `AIUR_GITHUB_BUDGET_KEY` from a caller. Only then does it derive the
|
|
72
|
-
# credential's stable identity — a caller that already picked the key has made
|
|
73
|
-
# the identity decision itself (#2353).
|
|
74
|
-
budget_key_derived=0
|
|
75
|
-
|
|
76
|
-
case "$budget_requested" in
|
|
77
|
-
0|false|FALSE|no|NO|off|OFF) budget_required=0 ;;
|
|
78
|
-
*) [ -n "$budget_root" ] && budget_required=1 ;;
|
|
79
|
-
esac
|
|
80
|
-
unset budget_requested
|
|
81
|
-
|
|
82
|
-
# #2356: agents carry no GITHUB_TOKEN/GH_TOKEN (Aiur.AgentEnvironment scrubs
|
|
83
|
-
# them). The credential comes from the file the daemon wrote and is injected
|
|
84
|
-
# only into the real `gh` child of THIS governed call, never the agent env or
|
|
85
|
-
# this wrapper's other children. The env fallback keeps host/Executor working.
|
|
86
|
-
guard_token=
|
|
87
|
-
if [ -n "${AIUR_GITHUB_CREDENTIAL_FILE:-}" ] && [ -f "$AIUR_GITHUB_CREDENTIAL_FILE" ]; then
|
|
88
|
-
guard_token=$(sed -n '1p' "$AIUR_GITHUB_CREDENTIAL_FILE" 2>/dev/null || true)
|
|
89
|
-
fi
|
|
90
|
-
[ -n "$guard_token" ] || guard_token=${GH_TOKEN:-${GITHUB_TOKEN:-}}
|
|
91
|
-
run_gh() {
|
|
92
|
-
if [ -n "${guard_token:-}" ]; then GH_TOKEN="$guard_token" GITHUB_TOKEN= "$real_gh" "$@"
|
|
93
|
-
else GITHUB_TOKEN= GH_TOKEN= "$real_gh" "$@"; fi
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
fingerprint_value() {
|
|
97
|
-
if command -v shasum >/dev/null 2>&1; then
|
|
98
|
-
printf '%s' "$1" | shasum -a 256 2>/dev/null | awk '{print $1}'
|
|
99
|
-
elif command -v sha256sum >/dev/null 2>&1; then
|
|
100
|
-
printf '%s' "$1" | sha256sum 2>/dev/null | awk '{print $1}'
|
|
101
|
-
else
|
|
102
|
-
return 1
|
|
103
|
-
fi
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
# The broker's stable one-way identity for a credential, domain-separated
|
|
107
|
-
# exactly as `Aiur.GitHub.Budget.identity_key/1` computes it for a machine
|
|
108
|
-
# user: sha256 of `aiur-github-credential-v1<NUL>machine_user:primary:<login>`.
|
|
109
|
-
# `\000` is the clear spelling of a NUL byte for POSIX printf, which treats `\0`
|
|
110
|
-
# as the start of an octal escape — so `\0` and `\000` produce the identical NUL
|
|
111
|
-
# and the hashed input is byte-identical to the Elixir side's
|
|
112
|
-
# `aiur-github-credential-v1\0machine_user:primary:<login>` either way.
|
|
113
|
-
identity_fingerprint() {
|
|
114
|
-
if command -v shasum >/dev/null 2>&1; then
|
|
115
|
-
printf 'aiur-github-credential-v1\000machine_user:primary:%s' "$1" | shasum -a 256 2>/dev/null | awk '{print $1}'
|
|
116
|
-
elif command -v sha256sum >/dev/null 2>&1; then
|
|
117
|
-
printf 'aiur-github-credential-v1\000machine_user:primary:%s' "$1" | sha256sum 2>/dev/null | awk '{print $1}'
|
|
118
|
-
else
|
|
119
|
-
return 1
|
|
120
|
-
fi
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
# Derives the credential's stable identity key for a host (non-agent) run that
|
|
124
|
-
# resolved its own token. `gh api user` reports the login of whichever
|
|
125
|
-
# credential the wrapper resolved (the bot's GITHUB_TOKEN, or the operator's
|
|
126
|
-
# keyring account), so the binding matches the token's identity. The derivation
|
|
127
|
-
# costs one Core request per new credential and is cached by token key under
|
|
128
|
-
# the budget root, so subsequent host calls reuse it.
|
|
129
|
-
#
|
|
130
|
-
# The derivation runs only for a call that is about to be admitted against a
|
|
131
|
-
# metered pool. A local credential read (`auth token`, `config`) must not pay a
|
|
132
|
-
# GitHub network round trip just to learn its own identity — the boot gate that
|
|
133
|
-
# consults `Config.keyring_token/0` would otherwise block offline, and the
|
|
134
|
-
# derivation's own request is unadmitted (#2353 review). A failed derivation is
|
|
135
|
-
# cached for `budget_identity_retry_ttl` seconds so an outage is not re-paid per
|
|
136
|
-
# call; within the window the call degrades to no identity key — the raw token
|
|
137
|
-
# hash is recorded, exactly as today — never to a wrong identity.
|
|
138
|
-
budget_derive_identity() {
|
|
139
|
-
[ -n "$budget_key" ] || return 0
|
|
140
|
-
[ -z "$budget_identity_key" ] || return 0
|
|
141
|
-
[ "$budget_key_derived" -eq 1 ] || return 0
|
|
142
|
-
[ "$budget_enabled" -eq 1 ] || return 0
|
|
143
|
-
[ "$admission_required" -eq 1 ] || return 0
|
|
144
|
-
[ "$resource" != none ] || return 0
|
|
145
|
-
|
|
146
|
-
identity_cache="$budget_root/identity-$budget_key"
|
|
147
|
-
budget_cached=
|
|
148
|
-
if [ -f "$identity_cache" ]; then
|
|
149
|
-
budget_cached=$(sed -n '1p' "$identity_cache" 2>/dev/null || true)
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
case "$budget_cached" in
|
|
153
|
-
"failed "*)
|
|
154
|
-
# A failed derivation is cached so an outage costs one `gh api user` per
|
|
155
|
-
# credential per window, not one per call. Once the window ages out, the
|
|
156
|
-
# next admitted call tries again, so a credential that was briefly
|
|
157
|
-
# offline still gets bound once GitHub is reachable.
|
|
158
|
-
budget_failed_at=${budget_cached#failed }
|
|
159
|
-
budget_now=$(date -u +%s 2>/dev/null || printf '')
|
|
160
|
-
if [ -n "$budget_failed_at" ] && [ -n "$budget_now" ] &&
|
|
161
|
-
[ "$budget_failed_at" -ge 0 ] 2>/dev/null && [ "$budget_now" -ge 0 ] 2>/dev/null &&
|
|
162
|
-
[ $((budget_now - budget_failed_at)) -lt $budget_identity_retry_ttl ]; then
|
|
163
|
-
unset budget_cached budget_failed_at budget_now
|
|
164
|
-
return 0
|
|
165
|
-
fi
|
|
166
|
-
unset budget_failed_at budget_now
|
|
167
|
-
;;
|
|
168
|
-
''|*[!0-9a-f]*)
|
|
169
|
-
: ;; # no cache, or a value that is not a hex identity key — re-derive
|
|
170
|
-
*)
|
|
171
|
-
budget_identity_key=$budget_cached
|
|
172
|
-
unset budget_cached
|
|
173
|
-
return 0
|
|
174
|
-
;;
|
|
175
|
-
esac
|
|
176
|
-
unset budget_cached
|
|
177
|
-
|
|
178
|
-
# Routed through `run_gh` (#2356): agents carry no GITHUB_TOKEN/GH_TOKEN, so a
|
|
179
|
-
# direct `$real_gh` call here would go out unauthenticated and derive an empty
|
|
180
|
-
# login, splitting one credential's usage across two identities.
|
|
181
|
-
budget_login=$(run_gh api user --jq .login 2>/dev/null || true)
|
|
182
|
-
# `Aiur.GitHub.Credential.stable_identity/1` downcases every identity part,
|
|
183
|
-
# so the shell derivation must too, or a login with any uppercase character
|
|
184
|
-
# would hash to a different identity key here than on the daemon side and
|
|
185
|
-
# split one credential across two identities in the usage report.
|
|
186
|
-
if command -v tr >/dev/null 2>&1; then
|
|
187
|
-
budget_login=$(printf '%s' "$budget_login" | tr '[:upper:]' '[:lower:]')
|
|
188
|
-
fi
|
|
189
|
-
case "$budget_login" in
|
|
190
|
-
''|*[!A-Za-z0-9_-]*)
|
|
191
|
-
budget_failed_at=$(date -u +%s 2>/dev/null || printf '')
|
|
192
|
-
case "$budget_failed_at" in
|
|
193
|
-
''|*[!0-9]*) : ;;
|
|
194
|
-
*) printf 'failed %s\n' "$budget_failed_at" > "$identity_cache" 2>/dev/null || true ;;
|
|
195
|
-
esac
|
|
196
|
-
unset budget_failed_at
|
|
197
|
-
return 0
|
|
198
|
-
;;
|
|
199
|
-
*)
|
|
200
|
-
budget_identity_key=$(identity_fingerprint "$budget_login") || budget_identity_key=
|
|
201
|
-
if [ -n "$budget_identity_key" ]; then
|
|
202
|
-
printf '%s\n' "$budget_identity_key" > "$identity_cache" 2>/dev/null || true
|
|
203
|
-
fi
|
|
204
|
-
;;
|
|
205
|
-
esac
|
|
206
|
-
unset budget_login
|
|
207
|
-
return 0
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if [ -n "$state_root" ]; then
|
|
211
|
-
quota_dir=$state_root/github-quota
|
|
212
|
-
mkdir -p "$quota_dir" 2>/dev/null || true
|
|
213
|
-
fi
|
|
214
|
-
|
|
215
|
-
if [ -z "$agent_quota_dir" ]; then agent_quota_dir=$quota_dir; fi
|
|
216
|
-
if [ -n "$agent_quota_dir" ]; then
|
|
217
|
-
events_file=$agent_quota_dir/agent-requests.tsv
|
|
218
|
-
mkdir -p "$agent_quota_dir" 2>/dev/null || true
|
|
219
|
-
fi
|
|
220
|
-
|
|
221
|
-
if [ "$budget_required" -eq 1 ]; then
|
|
222
|
-
if [ -z "$budget_broker" ] || [ ! -x "$budget_broker" ]; then
|
|
223
|
-
budget_unavailable_reason='broker executable is unavailable'
|
|
224
|
-
elif ! command -v python3 >/dev/null 2>&1; then
|
|
225
|
-
budget_unavailable_reason='python3 is unavailable'
|
|
226
|
-
elif ! mkdir -p "$budget_root" 2>/dev/null; then
|
|
227
|
-
budget_unavailable_reason='state directory is unavailable'
|
|
228
|
-
else
|
|
229
|
-
if [ -z "$budget_key" ]; then
|
|
230
|
-
# `guard_token` is the file credential (agents) or the inherited env
|
|
231
|
-
# token (host/Executor); the keyring read below feeds both too.
|
|
232
|
-
budget_token=$guard_token
|
|
233
|
-
if [ -z "$budget_token" ]; then
|
|
234
|
-
budget_token=$(GITHUB_TOKEN= GH_TOKEN= "$real_gh" auth token --hostname github.com 2>/dev/null || true)
|
|
235
|
-
[ -n "$budget_token" ] && guard_token=$budget_token
|
|
236
|
-
fi
|
|
237
|
-
|
|
238
|
-
if [ -z "$budget_token" ]; then
|
|
239
|
-
budget_unavailable_reason='GitHub credential is unavailable'
|
|
240
|
-
else
|
|
241
|
-
budget_key=$(fingerprint_value "$budget_token") || budget_key=
|
|
242
|
-
[ -n "$budget_key" ] || budget_unavailable_reason='credential fingerprint is unavailable'
|
|
243
|
-
budget_key_derived=1
|
|
244
|
-
fi
|
|
245
|
-
unset budget_token
|
|
246
|
-
fi
|
|
247
|
-
|
|
248
|
-
if [ -z "$budget_unavailable_reason" ]; then
|
|
249
|
-
budget_db=$budget_root/budget.sqlite3
|
|
250
|
-
budget_enabled=1
|
|
251
|
-
fi
|
|
252
|
-
fi
|
|
253
|
-
fi
|
|
254
|
-
|
|
255
|
-
if [ "$budget_enabled" -eq 1 ]; then
|
|
256
|
-
budget_consumer_key=$(fingerprint_value "$budget_consumer") || budget_consumer_key=
|
|
257
|
-
[ -n "$budget_consumer_key" ] || budget_consumer_key=shared
|
|
258
|
-
fi
|
|
259
|
-
# The raw identity is the human-readable actor label for the usage report; the
|
|
260
|
-
# consumer key above stays a fingerprint. Preserved separately so `usage` can
|
|
261
|
-
# name this caller even when AIUR_GITHUB_BUDGET_CONSUMER is not exported.
|
|
262
|
-
budget_consumer_label=${AIUR_GITHUB_BUDGET_CONSUMER:-"executor:${PPID:-$$}"}
|
|
263
|
-
unset budget_consumer
|
|
264
|
-
|
|
265
|
-
direction=read
|
|
266
|
-
track=1
|
|
267
|
-
resource=unknown
|
|
268
|
-
admission_required=1
|
|
269
|
-
admission_resource=unknown
|
|
270
|
-
endpoint_family=rest
|
|
271
|
-
api_paginated=0
|
|
272
|
-
# High-level (non-`gh api`) budgeted commands run with `GH_DEBUG=api` so this
|
|
273
|
-
# wrapper can observe the HTTP response status. `gh` keeps the status internal
|
|
274
|
-
# for those commands, which left every 304 from `pr view`/`issue view`/`search`
|
|
275
|
-
# billed as if it had cost quota (#2353). The debug transcript is consumed for
|
|
276
|
-
# the reconcile and then stripped, so the caller's stderr is unchanged.
|
|
277
|
-
high_level_debug=0
|
|
278
|
-
|
|
279
|
-
api_command_endpoint() {
|
|
280
|
-
shift
|
|
281
|
-
api_options=1
|
|
282
|
-
api_value_expected=0
|
|
283
|
-
|
|
284
|
-
for api_argument in "$@"; do
|
|
285
|
-
if [ "$api_options" -eq 0 ]; then
|
|
286
|
-
printf '%s\n' "$api_argument"
|
|
287
|
-
unset api_options api_value_expected api_argument
|
|
288
|
-
return 0
|
|
289
|
-
fi
|
|
290
|
-
|
|
291
|
-
if [ "$api_value_expected" -eq 1 ]; then
|
|
292
|
-
api_value_expected=0
|
|
293
|
-
continue
|
|
294
|
-
fi
|
|
295
|
-
|
|
296
|
-
case "$api_argument" in
|
|
297
|
-
--) api_options=0 ;;
|
|
298
|
-
--cache|-F|--field|-f|--raw-field|-H|--header|--hostname|--input|-q|--jq|-X|--method|-p|--preview|-t|--template) api_value_expected=1 ;;
|
|
299
|
-
--cache=*|--field=*|--raw-field=*|--header=*|--hostname=*|--input=*|--jq=*|--method=*|--preview=*|--template=*|-F*|-f*|-H*|-q*|-X*|-p*|-t*) : ;;
|
|
300
|
-
--*) : ;;
|
|
301
|
-
-*) : ;;
|
|
302
|
-
*)
|
|
303
|
-
printf '%s\n' "$api_argument"
|
|
304
|
-
unset api_options api_value_expected api_argument
|
|
305
|
-
return 0
|
|
306
|
-
;;
|
|
307
|
-
esac
|
|
308
|
-
done
|
|
309
|
-
|
|
310
|
-
unset api_options api_value_expected api_argument
|
|
311
|
-
return 1
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
case "${1:-} ${2:-}" in
|
|
315
|
-
# `/rate_limit` is accepted with or without its leading slash — the same
|
|
316
|
-
# spelling tolerance the GraphQL arm below has — so the free endpoint is
|
|
317
|
-
# never misbooked to `rest`/core (#2353).
|
|
318
|
-
"api rate_limit"|"api /rate_limit") resource=none; endpoint_family=rate_limit ;;
|
|
319
|
-
"api graphql"|"api /graphql")
|
|
320
|
-
resource=graphql
|
|
321
|
-
endpoint_family=graphql
|
|
322
|
-
api_options=1
|
|
323
|
-
for arg in "$@"; do
|
|
324
|
-
if [ "$api_options" -eq 1 ] && [ "$arg" = -- ]; then
|
|
325
|
-
api_options=0
|
|
326
|
-
continue
|
|
327
|
-
fi
|
|
328
|
-
[ "$api_options" -eq 1 ] || continue
|
|
329
|
-
case "$arg" in
|
|
330
|
-
*mutation*|*Mutation*) direction=write ;;
|
|
331
|
-
--paginate|--paginate=true) api_paginated=1 ;;
|
|
332
|
-
esac
|
|
333
|
-
done
|
|
334
|
-
unset api_options
|
|
335
|
-
;;
|
|
336
|
-
"api "*)
|
|
337
|
-
resource=core
|
|
338
|
-
endpoint=${2#/}
|
|
339
|
-
endpoint=${endpoint#repos/}
|
|
340
|
-
endpoint=${endpoint%%\?*}
|
|
341
|
-
endpoint=${endpoint%%\#*}
|
|
342
|
-
case "$endpoint" in
|
|
343
|
-
*/*/*) endpoint_family=$(printf '%s' "$endpoint" | cut -d/ -f3) ;;
|
|
344
|
-
*) endpoint_family=rest ;;
|
|
345
|
-
esac
|
|
346
|
-
prior=
|
|
347
|
-
api_options=1
|
|
348
|
-
for arg in "$@"; do
|
|
349
|
-
if [ "$api_options" -eq 1 ] && [ "$arg" = -- ]; then
|
|
350
|
-
api_options=0
|
|
351
|
-
continue
|
|
352
|
-
fi
|
|
353
|
-
[ "$api_options" -eq 1 ] || continue
|
|
354
|
-
if [ "$prior" = -X ] || [ "$prior" = --method ]; then
|
|
355
|
-
case "$arg" in GET|get) ;; *) direction=write ;; esac
|
|
356
|
-
fi
|
|
357
|
-
case "$arg" in
|
|
358
|
-
-XPOST|-XPATCH|-XPUT|-XDELETE|--method=POST|--method=PATCH|--method=PUT|--method=DELETE|-f|-F|--field|--raw-field|--field=*|--raw-field=*) direction=write ;;
|
|
359
|
-
--paginate|--paginate=true) api_paginated=1 ;;
|
|
360
|
-
esac
|
|
361
|
-
prior=$arg
|
|
362
|
-
done
|
|
363
|
-
unset api_options
|
|
364
|
-
;;
|
|
365
|
-
# `gh pr view|list|status|checks`, `gh issue view|list|status`, and
|
|
366
|
-
# `gh search *` speak GraphQL on the wire, so they book to the graphql
|
|
367
|
-
# resource — not core. They KEEP their descriptive families (pulls / issues /
|
|
368
|
-
# search): `endpoint_family` is also the lease-pool key and the audit
|
|
369
|
-
# histogram, so collapsing every GraphQL arm onto one family would merge four
|
|
370
|
-
# in-flight pools into one. The broker's hourly accounting buckets on the
|
|
371
|
-
# booked `resource`, not the family. `pr diff` is REST and stays in the pulls
|
|
372
|
-
# family with resource=core (it must not inherit the graphql booking from its
|
|
373
|
-
# read-arm sibling).
|
|
374
|
-
"pr view"|"pr list"|"pr status"|"pr checks") resource=graphql; endpoint_family=pulls ;;
|
|
375
|
-
"pr diff") resource=core; endpoint_family=pulls ;;
|
|
376
|
-
"issue view"|"issue list"|"issue status") resource=graphql; endpoint_family=issues ;;
|
|
377
|
-
"run view"|"run list"|"run watch") endpoint_family=actions ;;
|
|
378
|
-
# `gh search` splits across two wire transports (measured with GH_DEBUG=api):
|
|
379
|
-
# `search issues|prs` are GraphQL (`X-Ratelimit-Resource: graphql`); `search
|
|
380
|
-
# code|commits|repos|users` hit REST `/search/*`, metered against a third pool,
|
|
381
|
-
# `search` (~30 req/min). The `search` pool is its own resource so something
|
|
382
|
-
# paces against it; booking it to core or graphql mis-states the spend and
|
|
383
|
-
# protects the wrong window.
|
|
384
|
-
"search issues"|"search prs") resource=graphql; endpoint_family=search ;;
|
|
385
|
-
"search code"|"search commits"|"search repos"|"search users") resource=search; endpoint_family=search ;;
|
|
386
|
-
"search "*) resource=search; endpoint_family=search ;;
|
|
387
|
-
# The `pr`/`issue` write subcommands are a GraphQL/REST mix and must be
|
|
388
|
-
# classified per subcommand rather than as one bucket: `pr create|merge|review`
|
|
389
|
-
# and `issue create` mutate through GraphQL; the rest (close, reopen, comment,
|
|
390
|
-
# edit, ready, lock/unlock, update-branch, transfer, ...) are REST. Each keeps
|
|
391
|
-
# its descriptive pulls/issues family for the lease pool and books the resource
|
|
392
|
-
# its wire traffic actually consumes.
|
|
393
|
-
"pr create"|"pr merge"|"pr review") resource=graphql; endpoint_family=pulls; direction=write ;;
|
|
394
|
-
"pr "*) resource=core; endpoint_family=pulls; direction=write ;;
|
|
395
|
-
"issue create") resource=graphql; endpoint_family=issues; direction=write ;;
|
|
396
|
-
"issue "*) resource=core; endpoint_family=issues; direction=write ;;
|
|
397
|
-
"run rerun"|"run cancel"|"run delete") endpoint_family=actions; direction=write ;;
|
|
398
|
-
"label create"|"label delete"|"label edit") endpoint_family=labels; direction=write ;;
|
|
399
|
-
# Commands that change repository state without touching an issue or a pull
|
|
400
|
-
# request. Left classified as reads they invalidated nothing, so
|
|
401
|
-
# `gh repo edit --default-branch` or a release could change what a stored
|
|
402
|
-
# answer says while every agent kept replaying the old one.
|
|
403
|
-
"repo edit"|"repo rename"|"repo archive"|"repo unarchive"|"repo delete"|\
|
|
404
|
-
"release create"|"release edit"|"release delete"|"release upload"|\
|
|
405
|
-
"secret set"|"secret delete"|"variable set"|"variable delete"|\
|
|
406
|
-
"gist create"|"gist edit"|"gist delete"|"cache delete") resource=core; direction=write ;;
|
|
407
|
-
"config "*|"alias "*|"completion "*|"help "*|"version "*) track=0; resource=none; admission_required=0 ;;
|
|
408
|
-
"auth token") track=0; resource=none; admission_required=0 ;;
|
|
409
|
-
"auth "*|"extension "*) track=0 ;;
|
|
410
|
-
esac
|
|
411
|
-
|
|
412
|
-
# `gh api` accepts options before its endpoint. Derive the resource family from
|
|
413
|
-
# that actual endpoint so a paginated `gh api -X GET repos/.../issues` uses the
|
|
414
|
-
# same per-endpoint ceiling as its unflagged form.
|
|
415
|
-
if [ "${1:-}" = api ]; then
|
|
416
|
-
resolved_api_endpoint=$(api_command_endpoint "$@") || resolved_api_endpoint=
|
|
417
|
-
|
|
418
|
-
case "$resolved_api_endpoint" in
|
|
419
|
-
rate_limit|/rate_limit)
|
|
420
|
-
resource=none
|
|
421
|
-
endpoint_family=rate_limit
|
|
422
|
-
;;
|
|
423
|
-
graphql|/graphql)
|
|
424
|
-
resource=graphql
|
|
425
|
-
endpoint_family=graphql
|
|
426
|
-
;;
|
|
427
|
-
*)
|
|
428
|
-
resource=core
|
|
429
|
-
resolved_endpoint=${resolved_api_endpoint#/}
|
|
430
|
-
resolved_endpoint=${resolved_endpoint#repos/}
|
|
431
|
-
resolved_endpoint=${resolved_endpoint%%\?*}
|
|
432
|
-
resolved_endpoint=${resolved_endpoint%%\#*}
|
|
433
|
-
case "$resolved_endpoint" in
|
|
434
|
-
*/*/*) endpoint_family=$(printf '%s' "$resolved_endpoint" | cut -d/ -f3) ;;
|
|
435
|
-
*) endpoint_family=rest ;;
|
|
436
|
-
esac
|
|
437
|
-
unset resolved_endpoint
|
|
438
|
-
;;
|
|
439
|
-
esac
|
|
440
|
-
|
|
441
|
-
unset resolved_api_endpoint
|
|
442
|
-
fi
|
|
443
|
-
|
|
444
|
-
# Fields imply POST only when the caller did not explicitly select a method.
|
|
445
|
-
# Recompute this after locating the endpoint so `gh api -X GET ... -f q=...`
|
|
446
|
-
# remains a budgeted read instead of being rejected as a paginated write.
|
|
447
|
-
if [ "${1:-}" = api ]; then
|
|
448
|
-
api_options=1
|
|
449
|
-
api_method=
|
|
450
|
-
api_payload=0
|
|
451
|
-
api_mutation=0
|
|
452
|
-
api_method_expected=0
|
|
453
|
-
|
|
454
|
-
for api_argument in "$@"; do
|
|
455
|
-
[ "$api_options" -eq 1 ] || continue
|
|
456
|
-
|
|
457
|
-
if [ "$api_method_expected" -eq 1 ]; then
|
|
458
|
-
api_method=$api_argument
|
|
459
|
-
api_method_expected=0
|
|
460
|
-
continue
|
|
461
|
-
fi
|
|
462
|
-
|
|
463
|
-
case "$api_argument" in
|
|
464
|
-
--) api_options=0 ;;
|
|
465
|
-
-X|--method) api_method_expected=1 ;;
|
|
466
|
-
-X*) api_method=${api_argument#-X} ;;
|
|
467
|
-
--method=*) api_method=${api_argument#--method=} ;;
|
|
468
|
-
-F|-f|--field|--raw-field|--input|--input=*) api_payload=1 ;;
|
|
469
|
-
-F*|-f*|--field=*|--raw-field=*) api_payload=1 ;;
|
|
470
|
-
*mutation*|*Mutation*) api_mutation=1 ;;
|
|
471
|
-
esac
|
|
472
|
-
done
|
|
473
|
-
|
|
474
|
-
case "$resource" in
|
|
475
|
-
graphql)
|
|
476
|
-
[ "$api_mutation" -eq 1 ] && direction=write || direction=read
|
|
477
|
-
;;
|
|
478
|
-
*)
|
|
479
|
-
case "$api_method" in
|
|
480
|
-
GET|get) direction=read ;;
|
|
481
|
-
'') [ "$api_payload" -eq 1 ] && direction=write || direction=read ;;
|
|
482
|
-
*) direction=write ;;
|
|
483
|
-
esac
|
|
484
|
-
;;
|
|
485
|
-
esac
|
|
486
|
-
|
|
487
|
-
unset api_options api_method api_payload api_mutation api_method_expected api_argument
|
|
488
|
-
fi
|
|
489
|
-
|
|
490
|
-
# #1793: direct GitHub issue API creation bypasses the `issue create`
|
|
491
|
-
# disposition enforcement below, so refuse it outright and point at the
|
|
492
|
-
# sanctioned path. Detect both REST issue endpoints and GraphQL `createIssue`
|
|
493
|
-
# mutations, including file- and stdin-backed GraphQL bodies. Paginated calls
|
|
494
|
-
# are owned by the pagination guard below, which already refuses every
|
|
495
|
-
# paginated write and non-replayable body, so leave those to it.
|
|
496
|
-
if [ "${1:-}" = api ] && [ "$api_paginated" -eq 0 ]; then
|
|
497
|
-
for direct_arg in "$@"; do
|
|
498
|
-
case "$direct_arg" in
|
|
499
|
-
*createIssue*|*CreateIssue*) direct_issue_api=1 ;;
|
|
500
|
-
esac
|
|
501
|
-
done
|
|
502
|
-
|
|
503
|
-
if [ "$direct_issue_api" -eq 0 ]; then
|
|
504
|
-
direct_endpoint=$(api_command_endpoint "$@") || direct_endpoint=
|
|
505
|
-
case "$direct_endpoint" in
|
|
506
|
-
# The collection endpoint, optionally with a trailing slash, query string,
|
|
507
|
-
# or fragment. `?` is escaped so it matches a literal `?`: unescaped it is
|
|
508
|
-
# a glob wildcard, which made this arm claim every issue *subresource*
|
|
509
|
-
# too — `issues/comments/<id>` most visibly, so an agent could not PATCH
|
|
510
|
-
# its own workpad comment. The #1793 guard is about creating issues, not
|
|
511
|
-
# editing one.
|
|
512
|
-
*repos/*/*/issues|*repos/*/*/issues/|\
|
|
513
|
-
*repos/*/*/issues\?*|*repos/*/*/issues/\?*|\
|
|
514
|
-
*repos/*/*/issues#*|*repos/*/*/issues/#*)
|
|
515
|
-
direct_method=
|
|
516
|
-
direct_payload=0
|
|
517
|
-
direct_method_expected=0
|
|
518
|
-
for direct_arg in "$@"; do
|
|
519
|
-
[ "$direct_method_expected" -eq 1 ] && { direct_method=$direct_arg; direct_method_expected=0; continue; }
|
|
520
|
-
case "$direct_arg" in
|
|
521
|
-
--) break ;;
|
|
522
|
-
-X|--method) direct_method_expected=1 ;;
|
|
523
|
-
-XGET|-X=GET|--method=GET|-Xget|-X=get|--method=get) direct_method=get ;;
|
|
524
|
-
-XPOST|-X=POST|--method=POST|-Xpost|-X=post|--method=post) direct_method=post ;;
|
|
525
|
-
-X*) direct_method=${direct_arg#-X} ;;
|
|
526
|
-
--method=*) direct_method=${direct_arg#--method=} ;;
|
|
527
|
-
-F|-f|--field|--raw-field|--input|--input=*) direct_payload=1 ;;
|
|
528
|
-
-F*|-f*|--field=*|--raw-field=*) direct_payload=1 ;;
|
|
529
|
-
esac
|
|
530
|
-
done
|
|
531
|
-
case "$direct_method" in
|
|
532
|
-
=*) direct_method=${direct_method#=} ;;
|
|
533
|
-
esac
|
|
534
|
-
case "$direct_method" in
|
|
535
|
-
GET|get) ;;
|
|
536
|
-
'') [ "$direct_payload" -eq 1 ] && direct_issue_api=1 ;;
|
|
537
|
-
*) direct_issue_api=1 ;;
|
|
538
|
-
esac
|
|
539
|
-
;;
|
|
540
|
-
esac
|
|
541
|
-
fi
|
|
542
|
-
|
|
543
|
-
# File- and stdin-backed GraphQL bodies are opaque to the argv scan above.
|
|
544
|
-
if [ "$direct_issue_api" -eq 0 ]; then
|
|
545
|
-
direct_graphql_file=
|
|
546
|
-
direct_prior=
|
|
547
|
-
for direct_arg in "$@"; do
|
|
548
|
-
case "$direct_prior" in
|
|
549
|
-
--input) direct_graphql_file=$direct_arg ;;
|
|
550
|
-
esac
|
|
551
|
-
case "$direct_arg" in
|
|
552
|
-
--input=*) direct_graphql_file=${direct_arg#--input=} ;;
|
|
553
|
-
query=@*|-Fquery=@*|-F=query=@*|-fquery=@*|-f=query=@*|--field=query=@*|--raw-field=query=@*) direct_graphql_file=${direct_arg#*@} ;;
|
|
554
|
-
esac
|
|
555
|
-
direct_prior=$direct_arg
|
|
556
|
-
done
|
|
557
|
-
if [ -n "$direct_graphql_file" ]; then
|
|
558
|
-
case "$direct_graphql_file" in
|
|
559
|
-
@*) direct_graphql_file=${direct_graphql_file#@} ;;
|
|
560
|
-
esac
|
|
561
|
-
# Only a body this process can read AND prove creates an issue is
|
|
562
|
-
# claimed by the #1793 guard. A stdin, unreadable, or otherwise opaque
|
|
563
|
-
# body cannot be confirmed as issue creation, so it is left to the
|
|
564
|
-
# pre-existing merge gate, which denies every unreadable GraphQL body
|
|
565
|
-
# because it cannot rule out a merge — claiming an opaque body here
|
|
566
|
-
# would mislabel a possible merge as issue creation.
|
|
567
|
-
if [ -f "$direct_graphql_file" ] && grep -q 'createIssue' "$direct_graphql_file" 2>/dev/null; then
|
|
568
|
-
direct_issue_api=1
|
|
569
|
-
fi
|
|
570
|
-
fi
|
|
571
|
-
fi
|
|
572
|
-
fi
|
|
573
|
-
|
|
574
|
-
if [ "$direct_issue_api" -eq 1 ]; then
|
|
575
|
-
printf '%s\n' 'aiur: refusing direct GitHub issue API creation (#1793).' >&2
|
|
576
|
-
printf '%s\n' 'aiur: use `gh issue create --label ...` so the dispatch disposition is explicit and enforceable.' >&2
|
|
577
|
-
exit 78
|
|
578
|
-
fi
|
|
579
|
-
|
|
580
|
-
dispatch_disposition() {
|
|
581
|
-
label=$1
|
|
582
|
-
case "$label" in
|
|
583
|
-
"$dispatch_prefix:todo"|human:todo|needs-triage|build-order|epic) return 0 ;;
|
|
584
|
-
*) return 1 ;;
|
|
585
|
-
esac
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
# #1793: a ticket created without a lifecycle label is undispatchable AND
|
|
589
|
-
# invisible — no agent can claim it and it appears in no state-scoped view, so
|
|
590
|
-
# it reads to the operator as "no work left" (29 accumulated in one run). The
|
|
591
|
-
# skills tell every filing path to set the disposition in the same request;
|
|
592
|
-
# this refuses the call that does not, because an unlabelled issue cannot be
|
|
593
|
-
# un-filed. Deliberately non-runnable hierarchy (Build Order roots, epics) and
|
|
594
|
-
# parked work still pass by naming their own disposition.
|
|
595
|
-
command_name=
|
|
596
|
-
subcommand_name=
|
|
597
|
-
# The third positional word, where `gh pr view 2073` and its siblings put the
|
|
598
|
-
# resource number. The shared-state cache reads the identity from exactly this
|
|
599
|
-
# position and nowhere else, so a rarer spelling such as
|
|
600
|
-
# `gh pr view --json body 2073` resolves to no identity and is simply not
|
|
601
|
-
# cached. Guessing a position instead would risk keying a response under the
|
|
602
|
-
# wrong number, and a wrong cached shape is worse than a cache miss.
|
|
603
|
-
positional_three=
|
|
604
|
-
positional_count=0
|
|
605
|
-
skip_root_value=0
|
|
606
|
-
for arg in "$@"; do
|
|
607
|
-
if [ "$skip_root_value" -eq 1 ]; then
|
|
608
|
-
skip_root_value=0
|
|
609
|
-
continue
|
|
610
|
-
fi
|
|
611
|
-
case "$arg" in
|
|
612
|
-
-R|--repo|--hostname) skip_root_value=1; continue ;;
|
|
613
|
-
-R?*|--repo=*|--hostname=*) continue ;;
|
|
614
|
-
esac
|
|
615
|
-
positional_count=$((positional_count + 1))
|
|
616
|
-
case "$positional_count" in
|
|
617
|
-
1) command_name=$arg ;;
|
|
618
|
-
2) subcommand_name=$arg ;;
|
|
619
|
-
*) positional_three=$arg; break ;;
|
|
620
|
-
esac
|
|
621
|
-
done
|
|
622
|
-
unset positional_count
|
|
623
|
-
command_key="$command_name $subcommand_name"
|
|
624
|
-
|
|
625
|
-
if [ "$command_key" = "issue create" ]; then
|
|
626
|
-
disposition=0
|
|
627
|
-
prior=
|
|
628
|
-
for arg in "$@"; do
|
|
629
|
-
label_value=
|
|
630
|
-
case "$arg" in
|
|
631
|
-
--label=*) label_value=${arg#--label=} ;;
|
|
632
|
-
-l?*) label_value=${arg#-l} ;;
|
|
633
|
-
*)
|
|
634
|
-
case "$prior" in
|
|
635
|
-
--label|-l) label_value=$arg ;;
|
|
636
|
-
esac
|
|
637
|
-
;;
|
|
638
|
-
esac
|
|
639
|
-
prior=$arg
|
|
640
|
-
[ -n "$label_value" ] || continue
|
|
641
|
-
# `gh` accepts repeated flags and comma-separated lists in one flag.
|
|
642
|
-
old_ifs=$IFS
|
|
643
|
-
IFS=,
|
|
644
|
-
for label in $label_value; do
|
|
645
|
-
if dispatch_disposition "$label"; then disposition=1; fi
|
|
646
|
-
done
|
|
647
|
-
IFS=$old_ifs
|
|
648
|
-
done
|
|
649
|
-
|
|
650
|
-
if [ "$disposition" -eq 0 ]; then
|
|
651
|
-
printf '%s\n' 'aiur: refusing `gh issue create` with no dispatch disposition (#1793).' >&2
|
|
652
|
-
printf '%s\n' 'aiur: an unlabelled ticket is undispatchable and invisible, so it reads as no work left.' >&2
|
|
653
|
-
printf 'aiur: pass --label %s:todo for executable work, or --label needs-triage / human:todo\n' "$dispatch_prefix" >&2
|
|
654
|
-
printf '%s\n' 'aiur: to park it deliberately, or --label build-order / epic for a non-runnable container.' >&2
|
|
655
|
-
exit 78
|
|
656
|
-
fi
|
|
657
|
-
fi
|
|
658
|
-
|
|
659
|
-
if [ "$validate_only" -eq 1 ]; then exit 0; fi
|
|
660
|
-
|
|
661
|
-
admission_resource=$resource
|
|
662
|
-
# Identity derivation needs the command's admission decision (resource /
|
|
663
|
-
# admission_required), which the classification above just made — so it runs
|
|
664
|
-
# here, not at the top of the script, and only for a call that is about to be
|
|
665
|
-
# admitted against a metered pool (`budget_derive_identity` re-checks the same
|
|
666
|
-
# gates). A local `auth token`/`config` read never pays a GitHub round trip.
|
|
667
|
-
budget_derive_identity
|
|
668
|
-
# `none` is the shared EndpointPolicy table's pool for endpoints GitHub does
|
|
669
|
-
# not meter (`/rate_limit`). They are admitted for ordering but their ledger
|
|
670
|
-
# row keeps `resource: none` — the same row the daemon's Budget path writes —
|
|
671
|
-
# rather than being booked onto the core bucket, so the guard and the daemon
|
|
672
|
-
# cannot disagree about what rate-limit probes cost (#2353). No `none`->core
|
|
673
|
-
# mapping is applied: the only admitted `none`-resource command is `api
|
|
674
|
-
# rate_limit`, and non-admitted `none` commands (config/auth token) never
|
|
675
|
-
# reach the broker.
|
|
676
|
-
|
|
677
|
-
# ---------------------------------------------------------------------------
|
|
678
|
-
# SECURITY INVARIANT — agents never approve or merge a pull request.
|
|
679
|
-
#
|
|
680
|
-
# The human merge gate is the last irreversible-action control in Aiur: an agent
|
|
681
|
-
# that can approve and merge its own PR removes every human from the loop, and
|
|
682
|
-
# prompt injection from a public issue body is enough to make it try.
|
|
683
|
-
#
|
|
684
|
-
# Two facts make this check work where an env-var switch would not:
|
|
685
|
-
#
|
|
686
|
-
# 1. Agent context is decided by WHERE THIS SCRIPT LIVES, not by an env var.
|
|
687
|
-
# The daemon installs an identical copy at `<workspace>/.aiur-runtime/bin/gh`
|
|
688
|
-
# for agents and at `~/.aiur/bin/gh` for the Executor. `$0` cannot be
|
|
689
|
-
# cleared with `env -u`, so `env -u AIUR_AGENT_WORKSPACE gh pr merge` still
|
|
690
|
-
# lands here as an agent.
|
|
691
|
-
# 2. It is paired with a per-agent `GH_CONFIG_DIR` (see
|
|
692
|
-
# `Aiur.AgentGitHubGuard.gh_config_dir/1`), which stops the documented
|
|
693
|
-
# bypass `env -u GITHUB_TOKEN -u GH_TOKEN gh pr review --approve`: with no
|
|
694
|
-
# keyring entry to fall back to, `gh` cannot reach the operator identity in
|
|
695
|
-
# the branch-protection `bypass_actors` list — even when the real `gh` is
|
|
696
|
-
# invoked by absolute path, because it is process environment, not a wrapper.
|
|
697
|
-
#
|
|
698
|
-
# Reads stay allowed: an agent must still inspect review state and whether a PR
|
|
699
|
-
# merged. Only the writes are refused.
|
|
700
|
-
# ---------------------------------------------------------------------------
|
|
701
|
-
# The redirect belongs to `cd`, not `pwd`: a missing directory must fail this
|
|
702
|
-
# command substitution silently instead of writing a shell error to the agent's
|
|
703
|
-
# stderr, where it would look like output from the command the agent ran.
|
|
704
|
-
guard_self_dir=$(CDPATH= cd "$(dirname "$0")" 2>/dev/null && pwd) || guard_self_dir=
|
|
705
|
-
agent_guard=0
|
|
706
|
-
case "$guard_self_dir" in
|
|
707
|
-
*/.aiur-runtime/bin) agent_guard=1 ;;
|
|
708
|
-
esac
|
|
709
|
-
[ -z "${AIUR_AGENT_WORKSPACE:-}" ] || agent_guard=1
|
|
710
|
-
unset guard_self_dir
|
|
711
|
-
|
|
712
|
-
# `--approve` is not a single spelling. gh accepts `--approve=true`, the short
|
|
713
|
-
# `-a`, and short clusters such as `-ab body`, so an exact-literal comparison
|
|
714
|
-
# refuses only the most obvious form. The scan must also skip the VALUES of
|
|
715
|
-
# value-taking flags, or `gh pr review --comment --body --approve` — a comment
|
|
716
|
-
# whose text happens to be `--approve` — is refused as an approval.
|
|
717
|
-
approve_flag_in_arguments() {
|
|
718
|
-
approve_options=1
|
|
719
|
-
approve_expect_value=0
|
|
720
|
-
|
|
721
|
-
for approve_argument in "$@"; do
|
|
722
|
-
[ "$approve_options" -eq 1 ] || continue
|
|
723
|
-
|
|
724
|
-
if [ "$approve_expect_value" -eq 1 ]; then
|
|
725
|
-
approve_expect_value=0
|
|
726
|
-
continue
|
|
727
|
-
fi
|
|
728
|
-
|
|
729
|
-
case "$approve_argument" in
|
|
730
|
-
--) approve_options=0 ;;
|
|
731
|
-
--approve|--approve=*)
|
|
732
|
-
unset approve_options approve_expect_value approve_argument approve_cluster
|
|
733
|
-
return 0
|
|
734
|
-
;;
|
|
735
|
-
--body|--body-file|--repo) approve_expect_value=1 ;;
|
|
736
|
-
--*) : ;;
|
|
737
|
-
-?*)
|
|
738
|
-
# Walk the cluster one letter at a time. A value-taking letter consumes
|
|
739
|
-
# the remainder of the cluster as its inline value (`-Rowner/aiur`), so
|
|
740
|
-
# stop there instead of reading that value as more flags.
|
|
741
|
-
approve_cluster=${approve_argument#-}
|
|
742
|
-
while [ -n "$approve_cluster" ]; do
|
|
743
|
-
case "$approve_cluster" in
|
|
744
|
-
a*)
|
|
745
|
-
unset approve_options approve_expect_value approve_argument approve_cluster
|
|
746
|
-
return 0
|
|
747
|
-
;;
|
|
748
|
-
b*|F*|R*)
|
|
749
|
-
approve_cluster=${approve_cluster#?}
|
|
750
|
-
[ -n "$approve_cluster" ] || approve_expect_value=1
|
|
751
|
-
approve_cluster=
|
|
752
|
-
;;
|
|
753
|
-
*) approve_cluster=${approve_cluster#?} ;;
|
|
754
|
-
esac
|
|
755
|
-
done
|
|
756
|
-
;;
|
|
757
|
-
esac
|
|
758
|
-
done
|
|
759
|
-
|
|
760
|
-
unset approve_options approve_expect_value approve_argument approve_cluster
|
|
761
|
-
return 1
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
# gh reads a GraphQL document from a file or standard input as readily as from
|
|
765
|
-
# argv. When it does, this process never sees the document, so the mutation-name
|
|
766
|
-
# scan below has nothing to match and would admit `addPullRequestReview` with
|
|
767
|
-
# the agent's PAT — an approval branch protection does not stop. The guard can
|
|
768
|
-
# only permit what it can read, so an unreadable body is a denial.
|
|
769
|
-
graphql_body_is_hidden() {
|
|
770
|
-
for deny_argument in "$@"; do
|
|
771
|
-
case "$deny_argument" in
|
|
772
|
-
--input|--input=*|*=@*|-)
|
|
773
|
-
unset deny_argument
|
|
774
|
-
return 0
|
|
775
|
-
;;
|
|
776
|
-
esac
|
|
777
|
-
done
|
|
778
|
-
unset deny_argument
|
|
779
|
-
return 1
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
merge_or_approve_command() {
|
|
783
|
-
case "${1:-} ${2:-}" in
|
|
784
|
-
"pr merge") return 0 ;;
|
|
785
|
-
"pr review") approve_flag_in_arguments "$@" && return 0 ;;
|
|
786
|
-
# A manually dispatched workflow runs with `GITHUB_TOKEN` and whatever
|
|
787
|
-
# permissions its YAML claims, entirely outside this guard — including
|
|
788
|
-
# `contents: write`. Dispatching one is a way to ask GitHub to perform the
|
|
789
|
-
# merge on the agent's behalf, so it is the same act as merging.
|
|
790
|
-
"workflow run") return 0 ;;
|
|
791
|
-
esac
|
|
792
|
-
|
|
793
|
-
[ "${1:-}" = api ] || return 1
|
|
794
|
-
|
|
795
|
-
if [ "$resource" = graphql ]; then
|
|
796
|
-
# This check precedes the read/write gate on purpose: a hidden body makes
|
|
797
|
-
# `direction` unknowable, and it is computed as `read` by default, so
|
|
798
|
-
# gating on it here would skip the denial entirely.
|
|
799
|
-
graphql_body_is_hidden "$@" && return 0
|
|
800
|
-
[ "$direction" = write ] || return 1
|
|
801
|
-
|
|
802
|
-
for deny_argument in "$@"; do
|
|
803
|
-
case "$deny_argument" in
|
|
804
|
-
*mergePullRequest*|*addPullRequestReview*|*submitPullRequestReview*|*enablePullRequestAutoMerge*)
|
|
805
|
-
unset deny_argument
|
|
806
|
-
return 0
|
|
807
|
-
;;
|
|
808
|
-
esac
|
|
809
|
-
done
|
|
810
|
-
unset deny_argument
|
|
811
|
-
return 1
|
|
812
|
-
fi
|
|
813
|
-
|
|
814
|
-
# A GET of `.../pulls/N/reviews` is how an agent checks whether review
|
|
815
|
-
# happened; only the write forms are the gate bypass.
|
|
816
|
-
[ "$direction" = write ] || return 1
|
|
817
|
-
|
|
818
|
-
deny_endpoint=$(api_command_endpoint "$@") || deny_endpoint=
|
|
819
|
-
deny_endpoint=${deny_endpoint%%\?*}
|
|
820
|
-
deny_endpoint=${deny_endpoint%%\#*}
|
|
821
|
-
deny_endpoint=${deny_endpoint%/}
|
|
822
|
-
case "$deny_endpoint" in
|
|
823
|
-
# `pulls/N/merge` and `pulls/N/reviews` are the direct forms. The rest reach
|
|
824
|
-
# the same result without a pull request at all: `merges` commits a merge
|
|
825
|
-
# onto a branch, a write to `git/refs` moves the protected branch to any
|
|
826
|
-
# commit, and `update-branch` writes to the PR's base-tracking ref.
|
|
827
|
-
*/pulls/*/merge|*/pulls/*/reviews|*/pulls/*/reviews/*|*/pulls/*/update-branch|*/merges|*/git/refs|*/git/refs/*)
|
|
828
|
-
unset deny_endpoint
|
|
829
|
-
return 0
|
|
830
|
-
;;
|
|
831
|
-
# Disarming the gate is as good as passing it. Branch protection and
|
|
832
|
-
# rulesets are what make an agent's bot PAT unable to merge in the first
|
|
833
|
-
# place, so an agent that can rewrite them has removed the control every
|
|
834
|
-
# other denial here depends on.
|
|
835
|
-
*/branches/*/protection|*/branches/*/protection/*|*/rulesets|*/rulesets/*)
|
|
836
|
-
unset deny_endpoint
|
|
837
|
-
return 0
|
|
838
|
-
;;
|
|
839
|
-
# The REST forms of the workflow dispatch denied above, plus
|
|
840
|
-
# `repos/{o}/{r}/dispatches`, which triggers a `repository_dispatch`
|
|
841
|
-
# workflow the same way.
|
|
842
|
-
*/actions/workflows/*/dispatches|*/dispatches)
|
|
843
|
-
unset deny_endpoint
|
|
844
|
-
return 0
|
|
845
|
-
;;
|
|
846
|
-
esac
|
|
847
|
-
unset deny_endpoint
|
|
848
|
-
return 1
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
# The denylist keys on the command name, so anything that renames a command
|
|
852
|
-
# defeats it: `gh alias set zz "pr merge"` followed by `gh zz 7` arrives here as
|
|
853
|
-
# `zz`, matches nothing, and is admitted. The per-workspace `GH_CONFIG_DIR` that
|
|
854
|
-
# closes the keyring bypass also hands the agent a writable place to store that
|
|
855
|
-
# alias: refusing alias mutation removes the write half; refusing an unknown
|
|
856
|
-
# command name removes the read half — an unrecognised name is not one this
|
|
857
|
-
# guard has decided is safe, but one it cannot decide about at all.
|
|
858
|
-
undecidable_agent_command() {
|
|
859
|
-
case "${1:-} ${2:-}" in
|
|
860
|
-
"alias set"|"alias delete"|"alias import") return 0 ;;
|
|
861
|
-
esac
|
|
862
|
-
|
|
863
|
-
case "${1:-}" in
|
|
864
|
-
# Bare `gh` and its top-level flags print local help; no command is run.
|
|
865
|
-
''|-*) return 1 ;;
|
|
866
|
-
accessibility|alias|api|attestation|auth|browse|cache|codespace|completion) return 1 ;;
|
|
867
|
-
config|extension|gist|gpg-key|help|issue|label|org|pr|preview|project) return 1 ;;
|
|
868
|
-
release|repo|ruleset|run|search|secret|ssh-key|status|variable|version|workflow) return 1 ;;
|
|
869
|
-
*) return 0 ;;
|
|
870
|
-
esac
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
if [ "$agent_guard" -eq 1 ] && merge_or_approve_command "$@"; then
|
|
874
|
-
printf '%s\n' 'aiur: agents cannot approve or merge pull requests; a human reviewer holds the merge gate' >&2
|
|
875
|
-
exit 77
|
|
876
|
-
fi
|
|
877
|
-
|
|
878
|
-
if [ "$agent_guard" -eq 1 ] && undecidable_agent_command "$@"; then
|
|
879
|
-
printf '%s\n' 'aiur: agents cannot rename or hide gh commands from the merge gate; refusing a command this guard cannot inspect' >&2
|
|
880
|
-
exit 77
|
|
881
|
-
fi
|
|
882
|
-
|
|
883
|
-
if [ "$admission_required" -eq 1 ] && [ "$budget_required" -eq 1 ] && [ "$budget_enabled" -ne 1 ]; then
|
|
884
|
-
printf 'aiur: GitHub shared budget unavailable (%s; %s); refusing uncoordinated request\n' "$budget_unavailable_reason" "$budget_recovery" >&2
|
|
885
|
-
exit 75
|
|
886
|
-
fi
|
|
887
|
-
|
|
888
|
-
consumer=unattributed
|
|
889
|
-
if [ -n "${AIUR_AGENT_WORKSPACE:-}" ]; then
|
|
890
|
-
ticket=$(basename "$AIUR_AGENT_WORKSPACE")
|
|
891
|
-
case "$ticket" in
|
|
892
|
-
''|*[!0-9]*) ;;
|
|
893
|
-
*) consumer=ticket:$ticket ;;
|
|
894
|
-
esac
|
|
895
|
-
fi
|
|
896
|
-
|
|
897
|
-
# ---------------------------------------------------------------------------
|
|
898
|
-
# SHARED GITHUB STATE CACHE (#2073 U6)
|
|
899
|
-
#
|
|
900
|
-
# The broker rations permission but stores no answers; this section serves each
|
|
901
|
-
# answer once from a store every agent on the host shares. Three rules govern it:
|
|
902
|
-
#
|
|
903
|
-
# 1. REPLAY BYTES, NEVER RECONSTRUCT THEM. A hit returns the exact stdout the
|
|
904
|
-
# real `gh` produced for an invocation whose output-affecting arguments
|
|
905
|
-
# (`--json`, `--jq`, `--template`, tty) hash identically.
|
|
906
|
-
#
|
|
907
|
-
# 2. KEYED BY RESOURCE IDENTITY; THE SHAPE ONLY NAMES THE FILE.
|
|
908
|
-
# `<owner>/<repo>/<kind>/<id>/<shape>` — one marker invalidates every shape.
|
|
909
|
-
#
|
|
910
|
-
# 3. ANY DOUBT FALLS THROUGH: an unrecognised command, unknown repository,
|
|
911
|
-
# missing store, unparseable entry or non-zero exit leaves `$cache_body`
|
|
912
|
-
# empty and the call proceeds as today. The cache may cost throughput when
|
|
913
|
-
# it fails, never correctness.
|
|
914
|
-
#
|
|
915
|
-
# WHAT THIS IS NOT. Every agent runs as the SAME OS user and can write here,
|
|
916
|
-
# exactly as beside the shared budget database; real containment needs a
|
|
917
|
-
# separate UID per agent.
|
|
918
|
-
#
|
|
919
|
-
# CONDITIONAL REQUESTS (#2299): `gh api` reads revalidate with If-None-Match
|
|
920
|
-
# against a stored ETag and a served 304 is reconciled free; high-level reads
|
|
921
|
-
# are GraphQL with no validator and stay TTL-only — see apis/github.md.
|
|
922
|
-
# ---------------------------------------------------------------------------
|
|
923
|
-
# The store sits beside the budget broker's database, the one directory every
|
|
924
|
-
# agent on a host shares. It derives from the RAW env var rather than
|
|
925
|
-
# `$budget_root` (which defaults to `$HOME/.aiur/github-budget` when unset), so
|
|
926
|
-
# a harness that clears the budget root does not get a live cache in the
|
|
927
|
-
# operator's home directory.
|
|
928
|
-
cache_root=${AIUR_GITHUB_STATE_CACHE_ROOT:-}
|
|
929
|
-
if [ -z "$cache_root" ] && [ -n "${AIUR_GITHUB_BUDGET_ROOT:-}" ]; then
|
|
930
|
-
cache_root=${AIUR_GITHUB_BUDGET_ROOT%/}/state-cache
|
|
931
|
-
fi
|
|
932
|
-
case "$cache_root" in
|
|
933
|
-
/*) ;;
|
|
934
|
-
*) cache_root= ;;
|
|
935
|
-
esac
|
|
936
|
-
# Whether THIS call reads and writes entries. Kept separate from the store's
|
|
937
|
-
# existence on purpose: the store is shared by every agent on the host, so a
|
|
938
|
-
# process opting out of reading must still retire what it changes. Gating
|
|
939
|
-
# invalidation on the same switch would let one agent's `--json`-free shell or
|
|
940
|
-
# one test harness leave every OTHER agent serving a stale answer for the rest
|
|
941
|
-
# of the window.
|
|
942
|
-
cache_reads=1
|
|
943
|
-
case "${AIUR_GITHUB_STATE_CACHE_ENABLED:-1}" in
|
|
944
|
-
0|false|FALSE|no|NO|off|OFF) cache_reads=0 ;;
|
|
945
|
-
esac
|
|
946
|
-
|
|
947
|
-
# R10's strict-freshness bypass. A caller that must not be served stale — a
|
|
948
|
-
# merge decision, a CI verdict — sets this and pays for the round trip. Writes
|
|
949
|
-
# still invalidate, so the bypass never leaves a stale entry behind it.
|
|
950
|
-
cache_bypass=0
|
|
951
|
-
case "${AIUR_GITHUB_STATE_CACHE_BYPASS:-0}" in
|
|
952
|
-
1|true|TRUE|yes|YES|on|ON) cache_bypass=1 ;;
|
|
953
|
-
esac
|
|
954
|
-
|
|
955
|
-
# Seconds, because that is the resolution `date` gives without a subprocess per
|
|
956
|
-
# comparison. A sub-second value rounds to zero, which still serves an entry
|
|
957
|
-
# written in the same second, so the setting is documented in whole seconds and
|
|
958
|
-
# a sub-second value is treated as "off" rather than pretending to a precision
|
|
959
|
-
# the entry stamps do not carry.
|
|
960
|
-
cache_ttl=${AIUR_GITHUB_STATE_CACHE_TTL_MS:-60000}
|
|
961
|
-
case "$cache_ttl" in ''|*[!0-9]*) cache_ttl=60000 ;; esac
|
|
962
|
-
if [ "$cache_ttl" -lt 1000 ]; then
|
|
963
|
-
cache_reads=0
|
|
964
|
-
cache_ttl=0
|
|
965
|
-
else
|
|
966
|
-
cache_ttl=$((cache_ttl / 1000))
|
|
967
|
-
fi
|
|
968
|
-
cache_max_bytes=${AIUR_GITHUB_STATE_CACHE_MAX_BYTES:-1048576}
|
|
969
|
-
case "$cache_max_bytes" in ''|*[!0-9]*) cache_max_bytes=1048576 ;; esac
|
|
970
|
-
|
|
971
|
-
cache_owner=
|
|
972
|
-
cache_repo_name=
|
|
973
|
-
cache_kind=
|
|
974
|
-
cache_id=
|
|
975
|
-
cache_write_id=
|
|
976
|
-
cache_collection=0
|
|
977
|
-
cache_repo_dir=
|
|
978
|
-
cache_entry_dir=
|
|
979
|
-
cache_body=
|
|
980
|
-
cache_meta=
|
|
981
|
-
cache_stage=
|
|
982
|
-
cache_started_at=
|
|
983
|
-
cache_events_file=
|
|
984
|
-
cache_shape=
|
|
985
|
-
|
|
986
|
-
# `shasum`/`sha256sum` are how a shape becomes a filename. Without one there is
|
|
987
|
-
# no cache at all, which is the same safe no-op as an unset root.
|
|
988
|
-
cache_fingerprint() {
|
|
989
|
-
if command -v shasum >/dev/null 2>&1; then
|
|
990
|
-
shasum -a 256 2>/dev/null | cut -d' ' -f1
|
|
991
|
-
elif command -v sha256sum >/dev/null 2>&1; then
|
|
992
|
-
sha256sum 2>/dev/null | cut -d' ' -f1
|
|
993
|
-
else
|
|
994
|
-
return 1
|
|
995
|
-
fi
|
|
996
|
-
}
|
|
997
|
-
|
|
998
|
-
cache_valid_digest() {
|
|
999
|
-
case "$1" in
|
|
1000
|
-
''|*[!0-9a-f]*) return 1 ;;
|
|
1001
|
-
esac
|
|
1002
|
-
[ "${#1}" -eq 64 ]
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
# Every argument is length-prefixed so no two argument vectors can serialise to
|
|
1006
|
-
# the same bytes — `["a b"]` and `["a", "b"]` must not share an entry. The
|
|
1007
|
-
# terminal and colour variables join them because `gh` renders differently on a
|
|
1008
|
-
# TTY, and an entry written by a piped agent must never be replayed to an
|
|
1009
|
-
# interactive Executor shell as if it were the same request.
|
|
1010
|
-
#
|
|
1011
|
-
# `cache_tty` is sampled at the top level because this function's own stdout is
|
|
1012
|
-
# the fingerprint pipe, where `[ -t 1 ]` is false for every caller.
|
|
1013
|
-
cache_tty=0
|
|
1014
|
-
[ -t 1 ] && cache_tty=1
|
|
1015
|
-
|
|
1016
|
-
cache_material() {
|
|
1017
|
-
printf 'aiur-gh-cache/v2\n%s\n' "$cache_tty"
|
|
1018
|
-
# The credential the answer was fetched with. Everything else the broker keeps
|
|
1019
|
-
# — budgets, leases, cooldowns — is already keyed by this fingerprint, and a
|
|
1020
|
-
# response body is more identity-dependent than any of them: a private repo one
|
|
1021
|
-
# token cannot see, the `permissions` object, a collaborator list. Two
|
|
1022
|
-
# identities sharing one store must not share one answer.
|
|
1023
|
-
printf '%s\n' "${budget_key:-unkeyed}"
|
|
1024
|
-
printf '%s\n%s\n%s\n%s\n%s\n' "${NO_COLOR-}" "${CLICOLOR-}" "${CLICOLOR_FORCE-}" "${GH_FORCE_TTY-}" "${COLUMNS-}"
|
|
1025
|
-
printf '%s\n%s\n%s\n' "${GH_HOST-}" "${GH_REPO-}" "$#"
|
|
1026
|
-
for cache_arg in "$@"; do
|
|
1027
|
-
printf '%s\n%s\n' "${#cache_arg}" "$cache_arg"
|
|
1028
|
-
done
|
|
1029
|
-
unset cache_tty cache_arg
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
cache_valid_slug() {
|
|
1033
|
-
case "$1" in
|
|
1034
|
-
*[!A-Za-z0-9./_-]*|*..*|.*|*/) return 1 ;;
|
|
1035
|
-
*/*/*) return 1 ;;
|
|
1036
|
-
?*/?*) return 0 ;;
|
|
1037
|
-
esac
|
|
1038
|
-
return 1
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
cache_numeric() {
|
|
1042
|
-
case "$1" in
|
|
1043
|
-
''|*[!0-9]*) return 1 ;;
|
|
1044
|
-
esac
|
|
1045
|
-
[ "${#1}" -le 12 ]
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
# `https://github.com/OWNER/REPO/pull/2073` names its repository and its number
|
|
1049
|
-
# outright, so it is a stronger identity than the inferred slug below and
|
|
1050
|
-
# overrides it. Parsed with parameter expansion only — no subprocess.
|
|
1051
|
-
cache_read_url_identity() {
|
|
1052
|
-
case "$1" in
|
|
1053
|
-
https://github.com/*/*/pull/*|https://github.com/*/*/pulls/*|https://github.com/*/*/issues/*) ;;
|
|
1054
|
-
*) return 1 ;;
|
|
1055
|
-
esac
|
|
1056
|
-
|
|
1057
|
-
cache_url_rest=${1#https://github.com/}
|
|
1058
|
-
cache_url_owner=${cache_url_rest%%/*}
|
|
1059
|
-
cache_url_rest=${cache_url_rest#*/}
|
|
1060
|
-
cache_url_repo=${cache_url_rest%%/*}
|
|
1061
|
-
cache_url_rest=${cache_url_rest#*/}
|
|
1062
|
-
cache_url_type=${cache_url_rest%%/*}
|
|
1063
|
-
cache_url_number=${cache_url_rest#*/}
|
|
1064
|
-
cache_url_number=${cache_url_number%%/*}
|
|
1065
|
-
cache_url_number=${cache_url_number%%\?*}
|
|
1066
|
-
cache_url_number=${cache_url_number%%\#*}
|
|
1067
|
-
|
|
1068
|
-
if cache_valid_slug "$cache_url_owner/$cache_url_repo" && cache_numeric "$cache_url_number"; then
|
|
1069
|
-
cache_owner=$cache_url_owner
|
|
1070
|
-
cache_repo_name=$cache_url_repo
|
|
1071
|
-
cache_id=$cache_url_number
|
|
1072
|
-
case "$cache_url_type" in
|
|
1073
|
-
issues) cache_kind=issue ;;
|
|
1074
|
-
*) cache_kind=pr ;;
|
|
1075
|
-
esac
|
|
1076
|
-
unset cache_url_rest cache_url_owner cache_url_repo cache_url_type cache_url_number
|
|
1077
|
-
return 0
|
|
1078
|
-
fi
|
|
1079
|
-
|
|
1080
|
-
unset cache_url_rest cache_url_owner cache_url_repo cache_url_type cache_url_number
|
|
1081
|
-
return 1
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
|
-
if [ -n "$cache_root" ]; then
|
|
1085
|
-
# `--hostname` and `GH_HOST` move the request to another GitHub deployment
|
|
1086
|
-
# whose numbering is unrelated, so nothing is cached and — because entries of
|
|
1087
|
-
# THIS host must not be retired by a write against a different one — nothing
|
|
1088
|
-
# is invalidated either. A flag that names github.com explicitly is not a
|
|
1089
|
-
# different deployment, so it is compared rather than merely detected.
|
|
1090
|
-
cache_hostname_override=0
|
|
1091
|
-
cache_hostname_expected=0
|
|
1092
|
-
for cache_arg in "$@"; do
|
|
1093
|
-
if [ "$cache_hostname_expected" -eq 1 ]; then
|
|
1094
|
-
cache_hostname_expected=0
|
|
1095
|
-
case "$cache_arg" in
|
|
1096
|
-
github.com) ;;
|
|
1097
|
-
*) cache_hostname_override=1 ;;
|
|
1098
|
-
esac
|
|
1099
|
-
continue
|
|
1100
|
-
fi
|
|
1101
|
-
|
|
1102
|
-
case "$cache_arg" in
|
|
1103
|
-
--hostname) cache_hostname_expected=1 ;;
|
|
1104
|
-
--hostname=github.com) ;;
|
|
1105
|
-
--hostname=*) cache_hostname_override=1 ;;
|
|
1106
|
-
esac
|
|
1107
|
-
done
|
|
1108
|
-
unset cache_hostname_expected
|
|
1109
|
-
case "${GH_HOST:-github.com}" in
|
|
1110
|
-
github.com) ;;
|
|
1111
|
-
*) cache_hostname_override=1 ;;
|
|
1112
|
-
esac
|
|
1113
|
-
[ "$cache_hostname_override" -eq 0 ] || cache_root=
|
|
1114
|
-
unset cache_hostname_override cache_arg
|
|
1115
|
-
fi
|
|
1116
|
-
|
|
1117
|
-
if [ -n "$cache_root" ]; then
|
|
1118
|
-
# Repository identity, most explicit source first. The workspace anchor is
|
|
1119
|
-
# the subtle one: `AIUR_GITHUB_REPO` is the repo the daemon dispatched this
|
|
1120
|
-
# agent against, and `gh` resolves the repo from the working directory, so the
|
|
1121
|
-
# two only agree while the agent is inside its own workspace. An agent that
|
|
1122
|
-
# cloned something else and ran `gh pr view 5` there would have its answer
|
|
1123
|
-
# filed under the wrong repository — so that case resolves to no identity
|
|
1124
|
-
# and is not cached.
|
|
1125
|
-
cache_flag_repo=
|
|
1126
|
-
cache_prior=
|
|
1127
|
-
for cache_arg in "$@"; do
|
|
1128
|
-
case "$cache_prior" in
|
|
1129
|
-
-R|--repo) cache_flag_repo=$cache_arg ;;
|
|
1130
|
-
esac
|
|
1131
|
-
case "$cache_arg" in
|
|
1132
|
-
-R?*) cache_flag_repo=${cache_arg#-R} ;;
|
|
1133
|
-
--repo=*) cache_flag_repo=${cache_arg#--repo=} ;;
|
|
1134
|
-
esac
|
|
1135
|
-
cache_prior=$cache_arg
|
|
1136
|
-
done
|
|
1137
|
-
|
|
1138
|
-
cache_slug=
|
|
1139
|
-
if [ -n "$cache_flag_repo" ]; then
|
|
1140
|
-
cache_slug=$cache_flag_repo
|
|
1141
|
-
elif [ -n "${GH_REPO:-}" ]; then
|
|
1142
|
-
cache_slug=$GH_REPO
|
|
1143
|
-
elif [ -n "${AIUR_GITHUB_REPO:-}" ] && [ -n "${AIUR_AGENT_WORKSPACE:-}" ]; then
|
|
1144
|
-
case "${PWD:-}" in
|
|
1145
|
-
"$AIUR_AGENT_WORKSPACE"|"$AIUR_AGENT_WORKSPACE"/*) cache_slug=$AIUR_GITHUB_REPO ;;
|
|
1146
|
-
esac
|
|
1147
|
-
fi
|
|
1148
|
-
|
|
1149
|
-
if cache_valid_slug "$cache_slug"; then
|
|
1150
|
-
cache_owner=${cache_slug%%/*}
|
|
1151
|
-
cache_repo_name=${cache_slug#*/}
|
|
1152
|
-
fi
|
|
1153
|
-
|
|
1154
|
-
unset cache_flag_repo cache_prior cache_arg cache_slug
|
|
1155
|
-
fi
|
|
1156
|
-
|
|
1157
|
-
# The `--json` fields whose value is a verdict rather than a fact: CI state, and
|
|
1158
|
-
# whether a pull request can be merged. `gh pr checks` is excluded for the same
|
|
1159
|
-
# reason — and would have been unsafe in a second way: it exits 1 for failure
|
|
1160
|
-
# and 8 for pending while only a zero-status response is ever stored, so the
|
|
1161
|
-
# only verdict it could ever replay is "everything passed".
|
|
1162
|
-
cache_volatile_fields() {
|
|
1163
|
-
case ",$1," in
|
|
1164
|
-
*,statusCheckRollup,*|*,mergeable,*|*,mergeStateStatus,*|*,mergeCommit,*|\
|
|
1165
|
-
*,reviewDecision,*|*,latestReviews,*|*,reviews,*|*,state,*|*,merged,*|*,mergedAt,*|\
|
|
1166
|
-
*,closed,*|*,closedAt,*|*,headRefOid,*|*,commits,*) return 0 ;;
|
|
1167
|
-
esac
|
|
1168
|
-
return 1
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
# REST equivalents of the verdict and merge-gating fields above: a caller
|
|
1172
|
-
# spelling the same read as `gh api` must not acquire a stale answer merely by
|
|
1173
|
-
# bypassing `gh pr view`. The pull-request resource itself is included because
|
|
1174
|
-
# its default document carries `mergeable`, `mergeable_state`, `merged` and
|
|
1175
|
-
# `state` — the exact fields `gh pr view --json ...` refuses — and nothing that
|
|
1176
|
-
# changes them passes through this wrapper, so a `pulls/<n>/comments` read filed
|
|
1177
|
-
# under that PR can never be retired by the write that would stale it.
|
|
1178
|
-
#
|
|
1179
|
-
# Deliberate divergence from `Aiur.GitHub.ReadCache.Policy`: the daemon refuses
|
|
1180
|
-
# every `/actions` path wholesale; this wrapper keeps stable workflow metadata
|
|
1181
|
-
# (`actions/workflows`) cacheable and refuses only run and job state — a
|
|
1182
|
-
# workflow definition changes when its YAML is edited, a run's status is a
|
|
1183
|
-
# verdict nothing retires.
|
|
1184
|
-
cache_unsafe_rest_endpoint() {
|
|
1185
|
-
case "/${1#/}" in
|
|
1186
|
-
*/check-runs|*/check-runs/*|*/check-suites|*/check-suites/*|\
|
|
1187
|
-
*/status|*/status/*|*/statuses|*/statuses/*|\
|
|
1188
|
-
*/pulls|*/pulls/*|*/merge|*/merge/*|*/requested_reviewers|*/requested_reviewers/*|\
|
|
1189
|
-
*/reviews|*/reviews/*|*/actions/runs|*/actions/runs/*|\
|
|
1190
|
-
*/actions/jobs|*/actions/jobs/*|*/actions/workflows/*/runs|\
|
|
1191
|
-
*/actions/workflows/*/runs/*|*/actions/workflows/*/workflow_runs|\
|
|
1192
|
-
*/actions/workflows/*/workflow_runs/*) return 0 ;;
|
|
1193
|
-
*) return 1 ;;
|
|
1194
|
-
esac
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
|
-
# The output shapes this guard serves. Everything absent from this list — a
|
|
1198
|
-
# bare `gh pr view` with no number, `gh pr diff`, `gh api graphql`, every write
|
|
1199
|
-
# — falls through to the real `gh` untouched.
|
|
1200
|
-
#
|
|
1201
|
-
# `--json` is required for the high-level commands on purpose: without it `gh`
|
|
1202
|
-
# prints a human table with relative timestamps and terminal-width layout,
|
|
1203
|
-
# which is neither stable across agents nor meaningful to replay.
|
|
1204
|
-
if [ -n "$cache_root" ]; then
|
|
1205
|
-
cache_has_json=0
|
|
1206
|
-
cache_has_web=0
|
|
1207
|
-
cache_has_payload=0
|
|
1208
|
-
cache_volatile=0
|
|
1209
|
-
cache_options=1
|
|
1210
|
-
cache_expect_value=0
|
|
1211
|
-
cache_json_expected=0
|
|
1212
|
-
|
|
1213
|
-
for cache_arg in "$@"; do
|
|
1214
|
-
[ "$cache_options" -eq 1 ] || break
|
|
1215
|
-
|
|
1216
|
-
if [ "$cache_json_expected" -eq 1 ]; then
|
|
1217
|
-
cache_json_expected=0
|
|
1218
|
-
cache_expect_value=0
|
|
1219
|
-
cache_volatile_fields "$cache_arg" && cache_volatile=1
|
|
1220
|
-
continue
|
|
1221
|
-
fi
|
|
1222
|
-
|
|
1223
|
-
if [ "$cache_expect_value" -eq 1 ]; then
|
|
1224
|
-
cache_expect_value=0
|
|
1225
|
-
continue
|
|
1226
|
-
fi
|
|
1227
|
-
|
|
1228
|
-
case "$cache_arg" in
|
|
1229
|
-
--) cache_options=0 ;;
|
|
1230
|
-
--json|--jq|-q|--template|-t|--repo|-R|--hostname|--interval|-i|--limit|-L|--label|-l|\
|
|
1231
|
-
--assignee|-a|--author|-A|--search|-S|--state|-s|--base|-B|--head|-H|--milestone|-m|\
|
|
1232
|
-
--app|--mention|--cache|--header|--method|-X|--preview|-p)
|
|
1233
|
-
case "$cache_arg" in
|
|
1234
|
-
--json) cache_has_json=1; cache_json_expected=1 ;;
|
|
1235
|
-
esac
|
|
1236
|
-
cache_expect_value=1
|
|
1237
|
-
;;
|
|
1238
|
-
--json=*)
|
|
1239
|
-
cache_has_json=1
|
|
1240
|
-
cache_volatile_fields "${cache_arg#--json=}" && cache_volatile=1
|
|
1241
|
-
;;
|
|
1242
|
-
--web|-w) cache_has_web=1 ;;
|
|
1243
|
-
-F|-f|--field|--raw-field|--input) cache_has_payload=1; cache_expect_value=1 ;;
|
|
1244
|
-
-F*|-f*|--field=*|--raw-field=*|--input=*|*=@*|-) cache_has_payload=1 ;;
|
|
1245
|
-
esac
|
|
1246
|
-
done
|
|
1247
|
-
|
|
1248
|
-
# R10. A merge decision and a CI verdict may not be served stale, ever, and
|
|
1249
|
-
# neither may be repaired after the fact: an agent that reads "all green" for a
|
|
1250
|
-
# commit CI has not seen, or "mergeable" for a branch that has moved, has
|
|
1251
|
-
# already acted on it. Nothing invalidates these — `git push` and a check run
|
|
1252
|
-
# completing never pass through this wrapper — so the freshness window is the
|
|
1253
|
-
# ONLY thing standing between the read and a wrong answer. These field names
|
|
1254
|
-
# are refused outright, never given a short window.
|
|
1255
|
-
[ "$cache_volatile" -eq 0 ] || cache_reads=0
|
|
1256
|
-
|
|
1257
|
-
case "$command_key" in
|
|
1258
|
-
"pr view"|"issue view")
|
|
1259
|
-
if [ "$cache_has_json" -eq 1 ] && [ "$cache_has_web" -eq 0 ] && [ -n "$positional_three" ]; then
|
|
1260
|
-
if cache_numeric "$positional_three"; then
|
|
1261
|
-
cache_id=$positional_three
|
|
1262
|
-
case "$command_name" in
|
|
1263
|
-
pr) cache_kind=pr ;;
|
|
1264
|
-
*) cache_kind=issue ;;
|
|
1265
|
-
esac
|
|
1266
|
-
else
|
|
1267
|
-
cache_read_url_identity "$positional_three" || cache_id=
|
|
1268
|
-
fi
|
|
1269
|
-
fi
|
|
1270
|
-
;;
|
|
1271
|
-
"pr list"|"issue list")
|
|
1272
|
-
if [ "$cache_has_json" -eq 1 ] && [ "$cache_has_web" -eq 0 ]; then
|
|
1273
|
-
cache_id=list
|
|
1274
|
-
cache_collection=1
|
|
1275
|
-
case "$command_name" in
|
|
1276
|
-
pr) cache_kind=pr ;;
|
|
1277
|
-
*) cache_kind=issue ;;
|
|
1278
|
-
esac
|
|
1279
|
-
fi
|
|
1280
|
-
;;
|
|
1281
|
-
"api "*|"api")
|
|
1282
|
-
# REST GETs of a repository-scoped endpoint only. GraphQL is excluded:
|
|
1283
|
-
# its identity is an arbitrary document rather than a resource, so an
|
|
1284
|
-
# entry could not be invalidated by the resource writers above. Paginated
|
|
1285
|
-
# reads are excluded here and cached one page at a time, because the
|
|
1286
|
-
# pagination path re-enters this guard per page.
|
|
1287
|
-
if [ "$direction" = read ] && [ "$resource" = core ] && [ "$api_paginated" -eq 0 ] && [ "$cache_has_payload" -eq 0 ]; then
|
|
1288
|
-
cache_endpoint=$(api_command_endpoint "$@") || cache_endpoint=
|
|
1289
|
-
cache_endpoint=${cache_endpoint#/}
|
|
1290
|
-
# The query string is part of the SHAPE, which every argument is hashed
|
|
1291
|
-
# into anyway — it is not part of the resource's identity. Left on, a
|
|
1292
|
-
# `?per_page=1` moved the entry out of its resource's directory and into
|
|
1293
|
-
# a digest of the URL, where the resource's own writers cannot reach it.
|
|
1294
|
-
cache_endpoint=${cache_endpoint%%\?*}
|
|
1295
|
-
cache_endpoint=${cache_endpoint%%\#*}
|
|
1296
|
-
if cache_unsafe_rest_endpoint "$cache_endpoint"; then cache_reads=0; fi
|
|
1297
|
-
case "$cache_endpoint" in
|
|
1298
|
-
repos/*/*/*|repos/*/*)
|
|
1299
|
-
cache_api_rest=${cache_endpoint#repos/}
|
|
1300
|
-
cache_api_owner=${cache_api_rest%%/*}
|
|
1301
|
-
cache_api_rest=${cache_api_rest#*/}
|
|
1302
|
-
cache_api_repo=${cache_api_rest%%/*}
|
|
1303
|
-
if cache_valid_slug "$cache_api_owner/$cache_api_repo"; then
|
|
1304
|
-
cache_owner=$cache_api_owner
|
|
1305
|
-
cache_repo_name=$cache_api_repo
|
|
1306
|
-
|
|
1307
|
-
# An endpoint that NAMES a resource is filed under that resource,
|
|
1308
|
-
# not under the endpoint. `repos/o/r/pulls/1670` and
|
|
1309
|
-
# `gh pr view 1670 --json body` are the same pull request, so a
|
|
1310
|
-
# writer retiring pull request 1670 must retire both — and it
|
|
1311
|
-
# cannot if one is filed under a URL digest the writer has never
|
|
1312
|
-
# seen. The endpoint still separates the two entries via the
|
|
1313
|
-
# hashed shape.
|
|
1314
|
-
cache_api_number=
|
|
1315
|
-
case "$cache_api_rest" in
|
|
1316
|
-
*/issues/*|*/pulls/*)
|
|
1317
|
-
cache_api_tail=${cache_api_rest#*/}
|
|
1318
|
-
case "$cache_api_tail" in
|
|
1319
|
-
issues/*) cache_api_kind=issue; cache_api_tail=${cache_api_tail#issues/} ;;
|
|
1320
|
-
pulls/*) cache_api_kind=pr; cache_api_tail=${cache_api_tail#pulls/} ;;
|
|
1321
|
-
*) cache_api_kind= ;;
|
|
1322
|
-
esac
|
|
1323
|
-
cache_api_number=${cache_api_tail%%/*}
|
|
1324
|
-
if [ -n "$cache_api_kind" ] && cache_numeric "$cache_api_number"; then
|
|
1325
|
-
cache_kind=$cache_api_kind
|
|
1326
|
-
cache_id=$cache_api_number
|
|
1327
|
-
fi
|
|
1328
|
-
unset cache_api_tail cache_api_kind
|
|
1329
|
-
;;
|
|
1330
|
-
esac
|
|
1331
|
-
|
|
1332
|
-
if [ -z "$cache_id" ]; then
|
|
1333
|
-
# An endpoint naming no single resource — a list, a search, a
|
|
1334
|
-
# repository-level read. Filed under the endpoint and treated as a
|
|
1335
|
-
# collection, so a write anywhere in the repository retires it.
|
|
1336
|
-
cache_kind=api
|
|
1337
|
-
cache_collection=1
|
|
1338
|
-
cache_id=$(printf '%s' "$cache_endpoint" | cache_fingerprint) || cache_id=
|
|
1339
|
-
cache_valid_digest "$cache_id" || cache_id=
|
|
1340
|
-
fi
|
|
1341
|
-
unset cache_api_number
|
|
1342
|
-
fi
|
|
1343
|
-
unset cache_api_rest cache_api_owner cache_api_repo
|
|
1344
|
-
;;
|
|
1345
|
-
esac
|
|
1346
|
-
unset cache_endpoint
|
|
1347
|
-
fi
|
|
1348
|
-
;;
|
|
1349
|
-
esac
|
|
1350
|
-
|
|
1351
|
-
unset cache_has_json cache_has_web cache_has_payload cache_volatile cache_options cache_expect_value \
|
|
1352
|
-
cache_json_expected cache_arg
|
|
1353
|
-
fi
|
|
1354
|
-
|
|
1355
|
-
# The number a write mutates. Pull requests and issues share one number space on
|
|
1356
|
-
# GitHub, so a comment posted through `gh issue comment 2073` changes what
|
|
1357
|
-
# `gh pr view 2073 --json comments` would answer. Both directories are marked.
|
|
1358
|
-
case "$command_key" in
|
|
1359
|
-
"pr create"|"issue create") cache_write_id=collection ;;
|
|
1360
|
-
"pr "*|"issue "*)
|
|
1361
|
-
if cache_numeric "$positional_three"; then cache_write_id=$positional_three; fi
|
|
1362
|
-
;;
|
|
1363
|
-
esac
|
|
1364
|
-
|
|
1365
|
-
if [ -n "$cache_root" ] && [ "$direction" = write ] && [ "${1:-}" = api ] && [ -z "$cache_write_id" ]; then
|
|
1366
|
-
cache_write_endpoint=$(api_command_endpoint "$@") || cache_write_endpoint=
|
|
1367
|
-
cache_write_endpoint=${cache_write_endpoint#/}
|
|
1368
|
-
cache_write_endpoint=${cache_write_endpoint%%\?*}
|
|
1369
|
-
case "$cache_write_endpoint" in
|
|
1370
|
-
repos/*/*/issues/*|repos/*/*/pulls/*)
|
|
1371
|
-
cache_write_rest=${cache_write_endpoint#repos/}
|
|
1372
|
-
cache_write_owner=${cache_write_rest%%/*}
|
|
1373
|
-
cache_write_rest=${cache_write_rest#*/}
|
|
1374
|
-
cache_write_repo=${cache_write_rest%%/*}
|
|
1375
|
-
cache_write_rest=${cache_write_rest#*/}
|
|
1376
|
-
cache_write_rest=${cache_write_rest#*/}
|
|
1377
|
-
cache_write_number=${cache_write_rest%%/*}
|
|
1378
|
-
if cache_valid_slug "$cache_write_owner/$cache_write_repo"; then
|
|
1379
|
-
cache_owner=$cache_write_owner
|
|
1380
|
-
cache_repo_name=$cache_write_repo
|
|
1381
|
-
|
|
1382
|
-
if cache_numeric "$cache_write_number"; then
|
|
1383
|
-
cache_write_id=$cache_write_number
|
|
1384
|
-
else
|
|
1385
|
-
# `issues/comments/<id>`, `pulls/comments/<id>`, `issues/events/<id>`:
|
|
1386
|
-
# a subresource whose own id is not an issue or pull request number.
|
|
1387
|
-
# The agent workpad is edited through exactly this shape.
|
|
1388
|
-
cache_write_id=subresource
|
|
1389
|
-
fi
|
|
1390
|
-
fi
|
|
1391
|
-
unset cache_write_rest cache_write_owner cache_write_repo cache_write_number
|
|
1392
|
-
;;
|
|
1393
|
-
repos/*/*/issues|repos/*/*/pulls)
|
|
1394
|
-
cache_write_rest=${cache_write_endpoint#repos/}
|
|
1395
|
-
cache_write_owner=${cache_write_rest%%/*}
|
|
1396
|
-
cache_write_rest=${cache_write_rest#*/}
|
|
1397
|
-
cache_write_repo=${cache_write_rest%%/*}
|
|
1398
|
-
if cache_valid_slug "$cache_write_owner/$cache_write_repo"; then
|
|
1399
|
-
cache_owner=$cache_write_owner
|
|
1400
|
-
cache_repo_name=$cache_write_repo
|
|
1401
|
-
cache_write_id=collection
|
|
1402
|
-
fi
|
|
1403
|
-
unset cache_write_rest cache_write_owner cache_write_repo
|
|
1404
|
-
;;
|
|
1405
|
-
esac
|
|
1406
|
-
unset cache_write_endpoint
|
|
1407
|
-
fi
|
|
1408
|
-
|
|
1409
|
-
if [ -n "$cache_root" ]; then
|
|
1410
|
-
cache_started_at=$(date -u +%s 2>/dev/null || printf '')
|
|
1411
|
-
case "$cache_started_at" in
|
|
1412
|
-
''|*[!0-9]*) cache_root= ;;
|
|
1413
|
-
esac
|
|
1414
|
-
fi
|
|
1415
|
-
|
|
1416
|
-
# `cache_now` is what freshness is measured against. It starts equal to the
|
|
1417
|
-
# process's start and is re-sampled only by a coalesced follower, which is the
|
|
1418
|
-
# one caller for whom "now" has genuinely moved since it started.
|
|
1419
|
-
cache_now=${cache_started_at:-0}
|
|
1420
|
-
|
|
1421
|
-
if [ -n "$cache_root" ] && [ -n "$cache_owner" ] && [ -n "$cache_repo_name" ]; then
|
|
1422
|
-
# Down-cased, exactly as `Aiur.GitHub.ResourceStore.key/4` does, because the
|
|
1423
|
-
# daemon and this wrapper must name one repository one way. `-R AIUR-Team/Aiur`
|
|
1424
|
-
# and a webhook's `aiur-team/aiur` are the same repository; filed apart, the
|
|
1425
|
-
# daemon would retire entries no agent reads while agents keep serving the
|
|
1426
|
-
# ones it meant to retire — wrong in the one direction a cache may not be.
|
|
1427
|
-
if command -v tr >/dev/null 2>&1; then
|
|
1428
|
-
cache_identity=$(printf '%s/%s' "$cache_owner" "$cache_repo_name" | tr '[:upper:]' '[:lower:]')
|
|
1429
|
-
case "$cache_identity" in
|
|
1430
|
-
?*/?*)
|
|
1431
|
-
cache_owner=${cache_identity%%/*}
|
|
1432
|
-
cache_repo_name=${cache_identity#*/}
|
|
1433
|
-
;;
|
|
1434
|
-
*) cache_root= ;;
|
|
1435
|
-
esac
|
|
1436
|
-
unset cache_identity
|
|
1437
|
-
else
|
|
1438
|
-
# No `tr`, no way to guarantee one spelling. Caching nothing is the safe
|
|
1439
|
-
# answer; a half-shared store is worse than none.
|
|
1440
|
-
cache_root=
|
|
1441
|
-
fi
|
|
1442
|
-
fi
|
|
1443
|
-
|
|
1444
|
-
if [ -n "$cache_root" ] && [ -n "$cache_owner" ] && [ -n "$cache_repo_name" ]; then
|
|
1445
|
-
cache_repo_dir=$cache_root/v1/$cache_owner/$cache_repo_name
|
|
1446
|
-
fi
|
|
1447
|
-
|
|
1448
|
-
if [ "$cache_reads" -eq 1 ] && [ -n "$cache_repo_dir" ] && [ -n "$cache_kind" ] && [ -n "$cache_id" ]; then
|
|
1449
|
-
cache_shape=$(cache_material "$@" | cache_fingerprint) || cache_shape=
|
|
1450
|
-
if cache_valid_digest "$cache_shape"; then
|
|
1451
|
-
cache_entry_dir=$cache_repo_dir/$cache_kind/$cache_id
|
|
1452
|
-
cache_body=$cache_entry_dir/$cache_shape.body
|
|
1453
|
-
cache_meta=$cache_entry_dir/$cache_shape.meta
|
|
1454
|
-
else
|
|
1455
|
-
cache_shape=
|
|
1456
|
-
fi
|
|
1457
|
-
fi
|
|
1458
|
-
|
|
1459
|
-
if [ -n "$agent_quota_dir" ]; then cache_events_file=$agent_quota_dir/agent-cache.tsv; fi
|
|
1460
|
-
|
|
1461
|
-
# U8 attribution and U9's debug page read this: one row per cacheable
|
|
1462
|
-
# invocation, so agent-side effectiveness is a counted fact rather than an
|
|
1463
|
-
# inference from falling request rates.
|
|
1464
|
-
cache_record() {
|
|
1465
|
-
[ -n "$cache_events_file" ] || return 0
|
|
1466
|
-
|
|
1467
|
-
cache_events_size=0
|
|
1468
|
-
if [ -f "$cache_events_file" ]; then
|
|
1469
|
-
cache_events_size=$(wc -c < "$cache_events_file" 2>/dev/null || printf '0')
|
|
1470
|
-
fi
|
|
1471
|
-
case "$cache_events_size" in
|
|
1472
|
-
''|*[!0-9]*) cache_events_size=0 ;;
|
|
1473
|
-
esac
|
|
1474
|
-
if [ "$cache_events_size" -gt 1048576 ]; then
|
|
1475
|
-
# Timestamped rotations retain the complete 24-hour measurement window.
|
|
1476
|
-
# The pid keeps simultaneous writers from replacing one another's archive;
|
|
1477
|
-
# row timestamps, not filenames, decide which samples enter the ratio.
|
|
1478
|
-
mv -f "$cache_events_file" "$cache_events_file.$cache_started_at.$$" 2>/dev/null || true
|
|
1479
|
-
|
|
1480
|
-
# Pruning is outside the call's output descriptors and keeps a one-hour
|
|
1481
|
-
# safety margin beyond the reader's window. `-mmin` and `-delete` are
|
|
1482
|
-
# non-POSIX, so this is gated exactly as `cache_prune` gates its own use of
|
|
1483
|
-
# them: on a host without GNU/BSD find the prune is a no-op rather than a
|
|
1484
|
-
# silent failure that lets archives accumulate.
|
|
1485
|
-
if command -v find >/dev/null 2>&1; then
|
|
1486
|
-
(
|
|
1487
|
-
find "$agent_quota_dir" -type f -name 'agent-cache.tsv.*' -mmin +1500 -delete || true
|
|
1488
|
-
) >/dev/null 2>&1 &
|
|
1489
|
-
fi
|
|
1490
|
-
fi
|
|
1491
|
-
|
|
1492
|
-
# Sixth column: the miss reason, written on every miss (#2299). Hits, stores
|
|
1493
|
-
# and coalesced replays are 5-column rows by design.
|
|
1494
|
-
if [ -n "${2:-}" ]; then
|
|
1495
|
-
printf '%s\t%s\t%s\t%s\t%s\t%s\n' "$cache_started_at" "$consumer" "$1" "${cache_kind:-unknown}" "${cache_id:-unknown}" "$2" \
|
|
1496
|
-
>> "$cache_events_file" 2>/dev/null || true
|
|
1497
|
-
else
|
|
1498
|
-
printf '%s\t%s\t%s\t%s\t%s\n' "$cache_started_at" "$consumer" "$1" "${cache_kind:-unknown}" "${cache_id:-unknown}" \
|
|
1499
|
-
>> "$cache_events_file" 2>/dev/null || true
|
|
1500
|
-
fi
|
|
1501
|
-
unset cache_events_size
|
|
1502
|
-
return 0
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
# Reads use the shell's own `read` rather than `sed` so a hit spends no
|
|
1506
|
-
# subprocess on freshness at all. #1984 measures the broker at 250-450ms and
|
|
1507
|
-
# two `python3` spawns per call; a cache that added its own spawns to every
|
|
1508
|
-
# lookup would hand back what it saved.
|
|
1509
|
-
cache_marker_at() {
|
|
1510
|
-
[ -f "$1" ] || return 0
|
|
1511
|
-
|
|
1512
|
-
cache_marker_value=
|
|
1513
|
-
IFS= read -r cache_marker_value < "$1" 2>/dev/null || cache_marker_value=
|
|
1514
|
-
case "$cache_marker_value" in
|
|
1515
|
-
''|*[!0-9]*) cache_marker_value=0 ;;
|
|
1516
|
-
esac
|
|
1517
|
-
if [ "$cache_marker_value" -gt "$cache_invalidated_at" ]; then cache_invalidated_at=$cache_marker_value; fi
|
|
1518
|
-
unset cache_marker_value
|
|
1519
|
-
return 0
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
cache_lookup() {
|
|
1523
|
-
cache_miss_reason=absent
|
|
1524
|
-
[ -n "$cache_body" ] || return 1
|
|
1525
|
-
if [ "$cache_bypass" -ne 0 ]; then cache_miss_reason=bypassed; return 1; fi
|
|
1526
|
-
[ -f "$cache_meta" ] || return 1
|
|
1527
|
-
# A meta that survived but whose body did not is a torn entry, not a cold
|
|
1528
|
-
# read: `cache_prune` or a partial disk-full write left the stamp behind.
|
|
1529
|
-
# Recorded as `absent` it reads on the dashboard as a cold cache with diverse
|
|
1530
|
-
# shapes and store-integrity failures go unseen — the misdiagnosis #2207
|
|
1531
|
-
# exists to prevent. It is a distinct cause from `corrupt` (present but
|
|
1532
|
-
# unreadable) and from `absent` (nothing was ever stored).
|
|
1533
|
-
[ -f "$cache_body" ] || { cache_miss_reason=torn; return 1; }
|
|
1534
|
-
if [ ! -r "$cache_body" ]; then cache_miss_reason=corrupt; return 1; fi
|
|
1535
|
-
|
|
1536
|
-
cache_fetched_at=
|
|
1537
|
-
IFS= read -r cache_fetched_at < "$cache_meta" 2>/dev/null || { cache_miss_reason=corrupt; return 1; }
|
|
1538
|
-
case "$cache_fetched_at" in
|
|
1539
|
-
''|*[!0-9]*) cache_miss_reason=corrupt; return 1 ;;
|
|
1540
|
-
esac
|
|
1541
|
-
|
|
1542
|
-
# A clock that moved backwards, or an entry stamped in the future, is not
|
|
1543
|
-
# something to reason about — treat it as a miss and re-fetch.
|
|
1544
|
-
#
|
|
1545
|
-
# Compared against `$cache_now` rather than this process's start: a coalesced
|
|
1546
|
-
# follower looks again after waiting, and measured from its start an entry the
|
|
1547
|
-
# leader wrote one second later would read as stamped in the future and be
|
|
1548
|
-
# refused — precisely the duplicate fetch the wait existed to avoid.
|
|
1549
|
-
if [ "$cache_fetched_at" -gt "$cache_now" ]; then cache_miss_reason=clock-skewed; return 1; fi
|
|
1550
|
-
if [ $((cache_now - cache_fetched_at)) -gt "$cache_ttl" ]; then cache_miss_reason=expired; return 1; fi
|
|
1551
|
-
|
|
1552
|
-
cache_invalidated_at=0
|
|
1553
|
-
cache_marker_at "$cache_root/v1/.invalidated"
|
|
1554
|
-
cache_marker_at "$cache_repo_dir/.invalidated"
|
|
1555
|
-
[ "$cache_collection" -eq 0 ] || cache_marker_at "$cache_repo_dir/.collections-invalidated"
|
|
1556
|
-
cache_marker_at "$cache_entry_dir/.invalidated"
|
|
1557
|
-
|
|
1558
|
-
if [ "$cache_fetched_at" -le "$cache_invalidated_at" ]; then cache_miss_reason=invalidated; return 1; fi
|
|
1559
|
-
cache_miss_reason=
|
|
1560
|
-
return 0
|
|
1561
|
-
}
|
|
1562
|
-
|
|
1563
|
-
cache_write_file() {
|
|
1564
|
-
cache_write_target=$1
|
|
1565
|
-
cache_write_tmp=$1.$$.tmp
|
|
1566
|
-
|
|
1567
|
-
case "$cache_write_target" in
|
|
1568
|
-
*/*) mkdir -p "${cache_write_target%/*}" 2>/dev/null || { unset cache_write_target cache_write_tmp; return 1; } ;;
|
|
1569
|
-
esac
|
|
1570
|
-
|
|
1571
|
-
if printf '%s\n' "$2" > "$cache_write_tmp" 2>/dev/null &&
|
|
1572
|
-
mv -f "$cache_write_tmp" "$cache_write_target" 2>/dev/null; then
|
|
1573
|
-
unset cache_write_target cache_write_tmp
|
|
1574
|
-
return 0
|
|
1575
|
-
fi
|
|
1576
|
-
|
|
1577
|
-
rm -f "$cache_write_tmp" 2>/dev/null || true
|
|
1578
|
-
unset cache_write_target cache_write_tmp
|
|
1579
|
-
return 1
|
|
1580
|
-
}
|
|
1581
|
-
|
|
1582
|
-
# Marked with the moment the mutation FINISHED, and entries with the moment
|
|
1583
|
-
# their read STARTED. Both choices are load-bearing:
|
|
1584
|
-
#
|
|
1585
|
-
# * A read that began before the write completed is retired even if its
|
|
1586
|
-
# response arrived afterwards, because its stamp predates the marker.
|
|
1587
|
-
# Stamping the marker at the mutation's start would leave that read — which
|
|
1588
|
-
# cannot contain the change — looking newer than the change, and an agent
|
|
1589
|
-
# would be unable to see the comment it had just posted for the whole
|
|
1590
|
-
# window.
|
|
1591
|
-
# * The error runs one way only: a read that genuinely postdates the write is
|
|
1592
|
-
# also retired when it began within the same second, costing one re-fetch.
|
|
1593
|
-
# Over-invalidation is the only acceptable direction here.
|
|
1594
|
-
cache_invalidate_writes() {
|
|
1595
|
-
[ -n "$cache_root" ] || return 0
|
|
1596
|
-
[ "$direction" = write ] || return 0
|
|
1597
|
-
|
|
1598
|
-
cache_finished_at=$(date -u +%s 2>/dev/null || printf '')
|
|
1599
|
-
case "$cache_finished_at" in ''|*[!0-9]*) cache_finished_at=$cache_started_at ;; esac
|
|
1600
|
-
case "$cache_finished_at" in ''|*[!0-9]*) return 0 ;; esac
|
|
1601
|
-
|
|
1602
|
-
if [ -z "$cache_repo_dir" ]; then
|
|
1603
|
-
# A write whose repository could not be identified may have changed
|
|
1604
|
-
# anything, so nothing may be trusted. This is deliberately blunt: a rare
|
|
1605
|
-
# over-invalidation costs one re-fetch, while a missed one serves a stale
|
|
1606
|
-
# answer for the whole freshness window.
|
|
1607
|
-
cache_write_file "$cache_root/v1/.invalidated" "$cache_finished_at" || true
|
|
1608
|
-
unset cache_finished_at
|
|
1609
|
-
return 0
|
|
1610
|
-
fi
|
|
1611
|
-
|
|
1612
|
-
cache_write_file "$cache_repo_dir/.collections-invalidated" "$cache_finished_at" || true
|
|
1613
|
-
|
|
1614
|
-
case "$cache_write_id" in
|
|
1615
|
-
# A write whose subject is a SUBRESOURCE — a comment id, a review id — names
|
|
1616
|
-
# a number that is not an issue or pull request number, and the parent it
|
|
1617
|
-
# belongs to is not derivable from it. Retiring the repository for it would
|
|
1618
|
-
# be correct and ruinous: agents rewrite their workpad comment every few
|
|
1619
|
-
# minutes, so every edit would flush the whole store and the sharing this
|
|
1620
|
-
# exists for would never happen. The collections marker is the honest scope.
|
|
1621
|
-
collection|subresource) ;;
|
|
1622
|
-
''|*[!0-9]*) cache_write_file "$cache_repo_dir/.invalidated" "$cache_finished_at" || true ;;
|
|
1623
|
-
*)
|
|
1624
|
-
cache_write_file "$cache_repo_dir/pr/$cache_write_id/.invalidated" "$cache_finished_at" || true
|
|
1625
|
-
cache_write_file "$cache_repo_dir/issue/$cache_write_id/.invalidated" "$cache_finished_at" || true
|
|
1626
|
-
;;
|
|
1627
|
-
esac
|
|
1628
|
-
|
|
1629
|
-
unset cache_finished_at
|
|
1630
|
-
return 0
|
|
1631
|
-
}
|
|
1632
|
-
|
|
1633
|
-
cache_store() {
|
|
1634
|
-
[ -n "$cache_body" ] || return 0
|
|
1635
|
-
[ -n "$cache_stage" ] && [ -f "$cache_stage" ] || return 0
|
|
1636
|
-
[ "${status:-1}" -eq 0 ] || return 0
|
|
1637
|
-
|
|
1638
|
-
cache_size=$(wc -c < "$cache_stage" 2>/dev/null || printf '')
|
|
1639
|
-
case "$cache_size" in
|
|
1640
|
-
''|*[!0-9]*) unset cache_size; return 0 ;;
|
|
1641
|
-
esac
|
|
1642
|
-
if [ "$cache_size" -gt "$cache_max_bytes" ]; then unset cache_size; return 0; fi
|
|
1643
|
-
unset cache_size
|
|
1644
|
-
|
|
1645
|
-
mkdir -p "$cache_entry_dir" 2>/dev/null || return 0
|
|
1646
|
-
|
|
1647
|
-
cache_body_tmp=$cache_body.$$.tmp
|
|
1648
|
-
if cat "$cache_stage" > "$cache_body_tmp" 2>/dev/null && mv -f "$cache_body_tmp" "$cache_body" 2>/dev/null; then
|
|
1649
|
-
# The body lands first and the stamp commits the entry, so a reader that
|
|
1650
|
-
# finds a readable stamp always finds a complete body behind it. Line 1 of
|
|
1651
|
-
# the meta stays the fetched-at stamp (the only line `cache_lookup` reads);
|
|
1652
|
-
# line 2, when present, is the response ETag a later re-read validates
|
|
1653
|
-
# against (#2307 conditional reads). No other reader touches line 2.
|
|
1654
|
-
cache_meta_body=$cache_started_at
|
|
1655
|
-
if [ -n "$cache_response_etag" ]; then cache_meta_body="$cache_started_at
|
|
1656
|
-
$cache_response_etag"; fi
|
|
1657
|
-
cache_write_file "$cache_meta" "$cache_meta_body" || rm -f "$cache_body" 2>/dev/null || true
|
|
1658
|
-
cache_record store
|
|
1659
|
-
unset cache_meta_body
|
|
1660
|
-
else
|
|
1661
|
-
rm -f "$cache_body_tmp" 2>/dev/null || true
|
|
1662
|
-
fi
|
|
1663
|
-
|
|
1664
|
-
unset cache_body_tmp
|
|
1665
|
-
return 0
|
|
1666
|
-
}
|
|
1667
|
-
|
|
1668
|
-
# Entries are never read after their window closes, so retention exists only to
|
|
1669
|
-
# stop the store growing without bound. Backgrounded and rate-limited to once an
|
|
1670
|
-
# hour so it never appears in the latency of a call.
|
|
1671
|
-
cache_prune() {
|
|
1672
|
-
[ -n "$cache_root" ] || return 0
|
|
1673
|
-
[ -d "$cache_root/v1" ] || return 0
|
|
1674
|
-
command -v find >/dev/null 2>&1 || return 0
|
|
1675
|
-
|
|
1676
|
-
cache_pruned_at=0
|
|
1677
|
-
if [ -f "$cache_root/v1/.pruned" ]; then
|
|
1678
|
-
IFS= read -r cache_pruned_at < "$cache_root/v1/.pruned" 2>/dev/null || cache_pruned_at=0
|
|
1679
|
-
case "$cache_pruned_at" in
|
|
1680
|
-
''|*[!0-9]*) cache_pruned_at=0 ;;
|
|
1681
|
-
esac
|
|
1682
|
-
fi
|
|
1683
|
-
|
|
1684
|
-
if [ $((cache_started_at - cache_pruned_at)) -lt 3600 ]; then unset cache_pruned_at; return 0; fi
|
|
1685
|
-
unset cache_pruned_at
|
|
1686
|
-
cache_write_file "$cache_root/v1/.pruned" "$cache_started_at" || return 0
|
|
1687
|
-
|
|
1688
|
-
# The subshell's own descriptors are redirected, not just the `find`'s: a
|
|
1689
|
-
# background job keeping a copy of this script's stdout holds the pipe open,
|
|
1690
|
-
# and `$(gh pr view ...)` blocks on EOF — so an unredirected sweep would stall
|
|
1691
|
-
# the very command it was meant to be invisible to.
|
|
1692
|
-
(
|
|
1693
|
-
find "$cache_root/v1" -type f \( -name '*.body' -o -name '*.meta' \) -mmin +120 -delete || true
|
|
1694
|
-
) >/dev/null 2>&1 &
|
|
1695
|
-
|
|
1696
|
-
return 0
|
|
1697
|
-
}
|
|
1698
|
-
|
|
1699
|
-
# Answers with the stored bytes, or refuses. `cat` is checked because the entry
|
|
1700
|
-
# can go away between the readability test and the read, and an unchecked `cat`
|
|
1701
|
-
# would hand the agent empty stdout with exit 0, which `out=$(gh pr view N
|
|
1702
|
-
# --json body -q .body)` reads as "the body is empty". A refusal here falls
|
|
1703
|
-
# through to the real `gh`, the same answer every other doubt in this file
|
|
1704
|
-
# produces.
|
|
1705
|
-
cache_serve() {
|
|
1706
|
-
if ! cat "$cache_body"; then
|
|
1707
|
-
# Body vanished between lookup and read — the miss is `corrupt`, not `absent`.
|
|
1708
|
-
cache_miss_reason=corrupt
|
|
1709
|
-
return 1
|
|
1710
|
-
fi
|
|
1711
|
-
cache_record "$1"
|
|
1712
|
-
return 0
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
# A second look, with the clock re-sampled. Between a caller's own lookup and
|
|
1716
|
-
# the moment it is admitted to spend, another agent's identical fetch can land —
|
|
1717
|
-
# so every point where this call is about to reach GitHub asks once more first.
|
|
1718
|
-
# One `date` and a handful of stats against a network round trip.
|
|
1719
|
-
cache_recheck() {
|
|
1720
|
-
[ -n "$cache_body" ] || return 1
|
|
1721
|
-
|
|
1722
|
-
cache_now=$(date -u +%s 2>/dev/null || printf '%s' "$cache_started_at")
|
|
1723
|
-
case "$cache_now" in ''|*[!0-9]*) cache_now=$cache_started_at ;; esac
|
|
1724
|
-
|
|
1725
|
-
cache_lookup
|
|
1726
|
-
}
|
|
1727
|
-
|
|
1728
|
-
if cache_lookup && cache_serve hit; then
|
|
1729
|
-
exit 0
|
|
1730
|
-
fi
|
|
1731
|
-
|
|
1732
|
-
[ -z "$cache_body" ] || cache_record miss "${cache_miss_reason:-absent}"
|
|
1733
|
-
|
|
1734
|
-
# COALESCING (#2073 U6). A hit above costs no `python3` and no network, so the
|
|
1735
|
-
# store already removes the second and later reads of a resource. It cannot
|
|
1736
|
-
# remove the SIMULTANEOUS ones: agents that all look before any answers all
|
|
1737
|
-
# miss and all pay. So the miss path names the shape it is about to fetch, and
|
|
1738
|
-
# the broker — the one place every agent on the host meets under a transaction —
|
|
1739
|
-
# admits one fetcher per shape and tells the rest to wait, look again, and find
|
|
1740
|
-
# the leader's answer. The claim is bounded by its own TTL and the waiter's
|
|
1741
|
-
# patience, so a leader that dies costs one duplicate fetch, never a stall. A
|
|
1742
|
-
# caller demanding strict freshness refuses stored answers by definition, so it
|
|
1743
|
-
# takes no part in this.
|
|
1744
|
-
#
|
|
1745
|
-
# The key's members are all constrained: owner and repo pass `cache_valid_slug`
|
|
1746
|
-
# (`[A-Za-z0-9./_-]`, no `..`), the kind is a literal, the id is digits, `list`
|
|
1747
|
-
# or a hex digest, and the shape is a 64-character hex digest. That is what makes
|
|
1748
|
-
# the unquoted expansion into the broker's argument list below safe; relax
|
|
1749
|
-
# `cache_valid_slug` and this becomes argument injection.
|
|
1750
|
-
cache_claim_key=
|
|
1751
|
-
if [ -n "$cache_body" ] && [ -n "$cache_shape" ] && [ "$cache_bypass" -eq 0 ]; then
|
|
1752
|
-
cache_claim_key=$cache_owner/$cache_repo_name/$cache_kind/$cache_id/$cache_shape
|
|
1753
|
-
fi
|
|
1754
|
-
|
|
1755
|
-
# How long a follower waits for the leader before deciding it is not coming and
|
|
1756
|
-
# fetching for itself. Bounded on purpose: a wait that could outlast the call it
|
|
1757
|
-
# replaces would turn a saving into a hang. Measured against the CLOCK, not the
|
|
1758
|
-
# sleeps the broker advertised — each iteration also pays a `python3` start and
|
|
1759
|
-
# a SQLite write transaction, so counting only the advertised sleep understated
|
|
1760
|
-
# the real wait by more than 2x.
|
|
1761
|
-
cache_claim_wait_budget_ms=${AIUR_GITHUB_STATE_CACHE_WAIT_MS:-15000}
|
|
1762
|
-
case "$cache_claim_wait_budget_ms" in ''|*[!0-9]*) cache_claim_wait_budget_ms=15000 ;; esac
|
|
1763
|
-
cache_claim_wait_budget=$(( (cache_claim_wait_budget_ms + 999) / 1000 ))
|
|
1764
|
-
cache_claim_waited_ms=0
|
|
1765
|
-
cache_claim_overtake=0
|
|
1766
|
-
cache_served=0
|
|
1767
|
-
|
|
1768
|
-
budget_command() {
|
|
1769
|
-
if [ -n "$budget_identity_key" ]; then
|
|
1770
|
-
python3 "$budget_broker" "$@" --db "$budget_db" --token-key "$budget_key" --identity-key "$budget_identity_key"
|
|
1771
|
-
else
|
|
1772
|
-
python3 "$budget_broker" "$@" --db "$budget_db" --token-key "$budget_key"
|
|
1773
|
-
fi
|
|
1774
|
-
}
|
|
1775
|
-
|
|
1776
|
-
budget_sleep_ms() {
|
|
1777
|
-
budget_delay=$1
|
|
1778
|
-
case "$budget_delay" in ''|0|*[!0-9]*) return 1 ;; esac
|
|
1779
|
-
budget_seconds=$(awk "BEGIN { printf \"%.3f\", $budget_delay / 1000 }")
|
|
1780
|
-
sleep "$budget_seconds"
|
|
1781
|
-
}
|
|
1782
|
-
|
|
1783
|
-
valid_budget_lease() {
|
|
1784
|
-
case "$1" in ''|*[!0-9abcdef]*) return 1 ;; esac
|
|
1785
|
-
[ "${#1}" -eq 32 ]
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
valid_budget_hold_reset() {
|
|
1789
|
-
case "$1" in ''|*[!0-9]*) return 1 ;; esac
|
|
1790
|
-
|
|
1791
|
-
python3 - "$1" <<'PY'
|
|
1792
|
-
import sys
|
|
1793
|
-
import time
|
|
1794
|
-
|
|
1795
|
-
# Mirrors the Elixir-side bounded window in `GithubBudgetPause.parse/3`: a
|
|
1796
|
-
# reset no more than 24h in the future or 5 minutes in the past is a live
|
|
1797
|
-
# hold; anything older in the past is a stale or forged value and must not be
|
|
1798
|
-
# accepted as a typed hold (which would clamp to a zero delay and re-pause
|
|
1799
|
-
# immediately).
|
|
1800
|
-
reset_at_ms = int(sys.argv[1])
|
|
1801
|
-
now_ms = time.time_ns() // 1_000_000
|
|
1802
|
-
sys.exit(0 if now_ms - 300_000 <= reset_at_ms <= now_ms + 86_400_000 else 1)
|
|
1803
|
-
PY
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
budget_acquire() {
|
|
1807
|
-
[ "$budget_enabled" -eq 1 ] || return 0
|
|
1808
|
-
|
|
1809
|
-
# Free endpoints (the shared EndpointPolicy table marks only `rate_limit`
|
|
1810
|
-
# non-billable) are still admitted and leased for ordering, but their
|
|
1811
|
-
# admission row must be recorded non-billable so the ledger never reports
|
|
1812
|
-
# them as spend — the same `--billable 0` the daemon's Budget path passes
|
|
1813
|
-
# (#2353). The broker defaults to `1`, so omitting this would bill every
|
|
1814
|
-
# `/rate_limit` probe as core spend.
|
|
1815
|
-
budget_billable_flag=
|
|
1816
|
-
[ "$endpoint_family" = rate_limit ] && budget_billable_flag="--billable 0"
|
|
1817
|
-
|
|
1818
|
-
while :; do
|
|
1819
|
-
# Whatever this loop last waited for — a hold, a full lease table, another
|
|
1820
|
-
# agent's identical fetch — the answer may have arrived meanwhile. Looking
|
|
1821
|
-
# again is a stat and a `read`, so it is cheaper than any of the reasons the
|
|
1822
|
-
# loop is here.
|
|
1823
|
-
if [ "$cache_claim_waited_ms" -gt 0 ] && cache_recheck && cache_serve coalesced; then
|
|
1824
|
-
cache_served=1
|
|
1825
|
-
return 66
|
|
1826
|
-
fi
|
|
1827
|
-
|
|
1828
|
-
budget_ignore_flag=
|
|
1829
|
-
[ "$budget_ignore_token_cooldown" -eq 1 ] && budget_ignore_flag=--ignore-token-cooldown
|
|
1830
|
-
budget_cache_flags=
|
|
1831
|
-
if [ -n "$cache_claim_key" ]; then
|
|
1832
|
-
budget_cache_flags="--cache-key $cache_claim_key --cache-claim-ttl-ms $budget_lease_ttl_ms"
|
|
1833
|
-
[ "$cache_claim_overtake" -eq 1 ] && budget_cache_flags="$budget_cache_flags --cache-ignore-claim"
|
|
1834
|
-
fi
|
|
1835
|
-
if ! budget_result=$(budget_command acquire --resource "$admission_resource" --consumer-key "$budget_consumer_key" --consumer-label "$budget_consumer_label" --endpoint-family "$endpoint_family" \
|
|
1836
|
-
$budget_ignore_flag $budget_cache_flags $budget_billable_flag \
|
|
1837
|
-
--max-inflight "${AIUR_GITHUB_MAX_INFLIGHT:-4}" \
|
|
1838
|
-
--max-inflight-per-endpoint "${AIUR_GITHUB_MAX_INFLIGHT_PER_ENDPOINT:-2}" \
|
|
1839
|
-
--requests-per-minute "${AIUR_GITHUB_REQUESTS_PER_MINUTE:-120}" \
|
|
1840
|
-
--stagger-ms "${AIUR_GITHUB_STAGGER_MS:-75}" --lease-ttl-ms "$budget_lease_ttl_ms" \
|
|
1841
|
-
--core-limit "${AIUR_GITHUB_CORE_LIMIT_PER_HOUR:-0}" \
|
|
1842
|
-
--graphql-limit "${AIUR_GITHUB_GRAPHQL_LIMIT_PER_HOUR:-0}" \
|
|
1843
|
-
--search-limit "${AIUR_GITHUB_SEARCH_LIMIT_PER_HOUR:-0}" 2>&1); then
|
|
1844
|
-
# A broker that predates the ledger schema (the trigger refuses its
|
|
1845
|
-
# lease-less admission INSERT) or the ledger's version stamp cannot be
|
|
1846
|
-
# admitted to this ledger. That is exactly the stale-broker population
|
|
1847
|
-
# #2307 exists for, and failing closed here would turn a working-but-
|
|
1848
|
-
# over-billing workspace into a hard `gh` outage with zero alerts: acquire
|
|
1849
|
-
# aborts before a lease exists, so the reconcile marker machinery would
|
|
1850
|
-
# never run. Fail OPEN instead — the request proceeds uncoordinated, just
|
|
1851
|
-
# as the stale broker behaved before the ledger was versioned — and write
|
|
1852
|
-
# the marker once so the daemon raises a fleet alert.
|
|
1853
|
-
if budget_stale_abort "$budget_result"; then
|
|
1854
|
-
budget_mark_stale_broker acquire
|
|
1855
|
-
return 0
|
|
1856
|
-
fi
|
|
1857
|
-
printf 'aiur: GitHub budget broker unavailable (%s); refusing uncoordinated request\n' "$budget_recovery" >&2
|
|
1858
|
-
return 75
|
|
1859
|
-
fi
|
|
1860
|
-
unset budget_ignore_flag budget_cache_flags
|
|
1861
|
-
|
|
1862
|
-
# The broker's response is the last non-empty line of its output. Stderr is
|
|
1863
|
-
# merged into $budget_result above (2>&1) so a stale-broker abort's trigger
|
|
1864
|
-
# or stamp message reaches budget_stale_abort, but a HEALTHY broker's stderr
|
|
1865
|
-
# — a Python DeprecationWarning, a wrapper notice, a locale complaint —
|
|
1866
|
-
# must not corrupt the protocol parse. The response is single-line, so take
|
|
1867
|
-
# the last non-empty line and match on that, not on the merged stream
|
|
1868
|
-
# (#2307 review: the 2>&1 change had re-opened an outage on healthy brokers
|
|
1869
|
-
# whose prefix-matched grant was buried under stderr noise).
|
|
1870
|
-
budget_result=$(printf '%s\n' "$budget_result" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e '/^$/d' | tail -n 1)
|
|
1871
|
-
|
|
1872
|
-
case "$budget_result" in
|
|
1873
|
-
"granted "*)
|
|
1874
|
-
budget_lease=${budget_result#granted }
|
|
1875
|
-
if valid_budget_lease "$budget_lease"; then
|
|
1876
|
-
# Admitted, and therefore about to spend. A grant is proof this
|
|
1877
|
-
# workspace's broker is current for the ledger, so any stale-broker
|
|
1878
|
-
# marker left by an earlier structural failure is cleared here as well
|
|
1879
|
-
# as by the reconcile path — a refreshed workspace that never happens
|
|
1880
|
-
# to see a 304 must not keep alerting (#2307 review).
|
|
1881
|
-
budget_clear_stale_broker acquire
|
|
1882
|
-
# The window between this
|
|
1883
|
-
# call's own lookup and this grant is exactly where a simultaneous
|
|
1884
|
-
# reader's answer lands, and it is not covered by the claim: a caller
|
|
1885
|
-
# arriving after the leader released has no claim to wait behind and
|
|
1886
|
-
# would fetch a resource that is already in the store.
|
|
1887
|
-
if [ -n "$cache_claim_key" ] && cache_recheck && cache_serve coalesced; then
|
|
1888
|
-
cache_served=1
|
|
1889
|
-
budget_release
|
|
1890
|
-
return 66
|
|
1891
|
-
fi
|
|
1892
|
-
|
|
1893
|
-
return 0
|
|
1894
|
-
fi
|
|
1895
|
-
printf '%s\n' 'aiur: GitHub budget broker returned an invalid admission response' >&2
|
|
1896
|
-
return 75
|
|
1897
|
-
;;
|
|
1898
|
-
"hold shared "*)
|
|
1899
|
-
budget_hold=${budget_result#hold shared }
|
|
1900
|
-
budget_hold_resource=${budget_hold%% *}
|
|
1901
|
-
budget_hold_reset_at_ms=${budget_hold#* }
|
|
1902
|
-
case "$budget_hold_resource:$budget_hold_reset_at_ms" in
|
|
1903
|
-
core:*|graphql:*)
|
|
1904
|
-
if valid_budget_hold_reset "$budget_hold_reset_at_ms"; then
|
|
1905
|
-
printf 'aiur: github budget hold resource=%s reset_at_ms=%s\n' \
|
|
1906
|
-
"$budget_hold_resource" "$budget_hold_reset_at_ms" >&2
|
|
1907
|
-
return 75
|
|
1908
|
-
fi
|
|
1909
|
-
;;
|
|
1910
|
-
esac
|
|
1911
|
-
printf '%s\n' 'aiur: GitHub budget broker returned an invalid shared hold response' >&2
|
|
1912
|
-
return 75
|
|
1913
|
-
;;
|
|
1914
|
-
"wait "*)
|
|
1915
|
-
budget_wait_ms=${budget_result#wait }
|
|
1916
|
-
# An actor-ceiling hold is `wait actor <ms>`; the `actor` token is the
|
|
1917
|
-
# Elixir side's cue for the hold reason and is not part of the delay.
|
|
1918
|
-
budget_wait_ms=${budget_wait_ms#actor }
|
|
1919
|
-
if ! budget_sleep_ms "$budget_wait_ms"; then
|
|
1920
|
-
printf '%s\n' 'aiur: GitHub budget broker returned an invalid or unusable wait response' >&2
|
|
1921
|
-
return 75
|
|
1922
|
-
fi
|
|
1923
|
-
case "$budget_wait_ms" in
|
|
1924
|
-
''|*[!0-9]*) ;;
|
|
1925
|
-
*) cache_claim_waited_ms=$((cache_claim_waited_ms + budget_wait_ms)) ;;
|
|
1926
|
-
esac
|
|
1927
|
-
# Patience spent. The leader may have died between claiming the resource
|
|
1928
|
-
# and answering for it, and a follower that waits forever on a dead
|
|
1929
|
-
# leader has been made worse off by the optimisation. Overtake the claim
|
|
1930
|
-
# and fetch; the cost is the one call this was trying to save.
|
|
1931
|
-
if [ -n "$cache_claim_key" ] && [ "$cache_claim_overtake" -eq 0 ]; then
|
|
1932
|
-
cache_waited=$(date -u +%s 2>/dev/null || printf '')
|
|
1933
|
-
case "$cache_waited" in
|
|
1934
|
-
''|*[!0-9]*) ;;
|
|
1935
|
-
*)
|
|
1936
|
-
if [ $((cache_waited - cache_started_at)) -ge "$cache_claim_wait_budget" ]; then
|
|
1937
|
-
cache_claim_overtake=1
|
|
1938
|
-
fi
|
|
1939
|
-
;;
|
|
1940
|
-
esac
|
|
1941
|
-
unset cache_waited
|
|
1942
|
-
fi
|
|
1943
|
-
unset budget_wait_ms
|
|
1944
|
-
;;
|
|
1945
|
-
*)
|
|
1946
|
-
printf '%s\n' 'aiur: GitHub budget broker returned an invalid admission response' >&2
|
|
1947
|
-
return 75
|
|
1948
|
-
;;
|
|
1949
|
-
esac
|
|
1950
|
-
done
|
|
1951
|
-
}
|
|
1952
|
-
|
|
1953
|
-
budget_release() {
|
|
1954
|
-
if [ -n "$budget_renewal_pid" ]; then
|
|
1955
|
-
kill "$budget_renewal_pid" 2>/dev/null || true
|
|
1956
|
-
budget_renewal_pid=
|
|
1957
|
-
fi
|
|
1958
|
-
[ -n "$budget_lease" ] || return 0
|
|
1959
|
-
budget_command release --lease-id "$budget_lease" >/dev/null 2>&1 || true
|
|
1960
|
-
budget_lease=
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
# A stale-broker acquire abort: the ledger's schema trigger refused this
|
|
1964
|
-
# broker's lease-less admission INSERT, or the version stamp refused the write.
|
|
1965
|
-
# Both strings are this project's own (the trigger and `_ensure_writable`), so
|
|
1966
|
-
# this is not coupled to argparse or Python wording. Every other acquire failure
|
|
1967
|
-
# stays fail-closed exactly as before.
|
|
1968
|
-
budget_stale_abort() {
|
|
1969
|
-
case "$1" in
|
|
1970
|
-
*"refusing admission without a lease_id"*|*"refusing to write: ledger is stamped"*)
|
|
1971
|
-
return 0
|
|
1972
|
-
;;
|
|
1973
|
-
esac
|
|
1974
|
-
return 1
|
|
1975
|
-
}
|
|
1976
|
-
|
|
1977
|
-
# The marker write and the one-time stderr are the same event: the first
|
|
1978
|
-
# structural stale-broker failure in a period surfaces once, and every later
|
|
1979
|
-
# failure in that period (while the marker still stands) stays quiet so a fleet
|
|
1980
|
-
# of 304s does not become per-request noise (#2307). The daemon's quota reader
|
|
1981
|
-
# turns the marker into one fleet alert per workspace and rearms it when the
|
|
1982
|
-
# marker disappears (a refreshed broker self-heals). Line 1 is the consumer
|
|
1983
|
-
# label the daemon reads; line 2 records WHY the marker was written so the
|
|
1984
|
-
# guard can decide which recovery signal may clear it (#2307 review).
|
|
1985
|
-
budget_mark_stale_broker() {
|
|
1986
|
-
budget_stale_reason=$1
|
|
1987
|
-
if [ -n "$agent_quota_dir" ] && [ ! -f "$agent_quota_dir/broker-reconcile-stale" ]; then
|
|
1988
|
-
printf '%s\n%s\n' "$budget_consumer_label" "$budget_stale_reason" > "$agent_quota_dir/broker-reconcile-stale" 2>/dev/null || true
|
|
1989
|
-
printf '%s\n' 'aiur: GitHub budget broker is stale for this ledger (missing reconcile subcommand, or predates the ledger schema/version stamp); budget accounting for this workspace is disabled until the current broker is installed' >&2
|
|
1990
|
-
fi
|
|
1991
|
-
unset budget_stale_reason
|
|
1992
|
-
}
|
|
1993
|
-
|
|
1994
|
-
# Which recovery signal may clear the marker depends on why it was written.
|
|
1995
|
-
# acquire marker: the broker could not even be admitted to the ledger. The
|
|
1996
|
-
# first successful grant is proof the workspace now runs a broker
|
|
1997
|
-
# the daemon's release accepts, so it clears the marker even if
|
|
1998
|
-
# the workspace never happens to see a 304 (#2307 review).
|
|
1999
|
-
# reconcile marker: the broker IS admitted but cannot reconcile 304s. A later
|
|
2000
|
-
# grant does not prove reconcile works, so clearing on every grant
|
|
2001
|
-
# would re-alert on the next 304 — exactly the per-request noise
|
|
2002
|
-
# #2307 forbids. Only a successful reconcile clears it.
|
|
2003
|
-
# unknown (a marker written before this rework, single line): conservative —
|
|
2004
|
-
# cleared only by a successful reconcile, same as before.
|
|
2005
|
-
budget_clear_stale_broker() {
|
|
2006
|
-
budget_stale_signal=$1
|
|
2007
|
-
[ -n "$agent_quota_dir" ] && [ -f "$agent_quota_dir/broker-reconcile-stale" ] || { unset budget_stale_signal; return 0; }
|
|
2008
|
-
budget_marker_reason=$(sed -n '2p' "$agent_quota_dir/broker-reconcile-stale" 2>/dev/null || printf '')
|
|
2009
|
-
case "$budget_stale_signal:$budget_marker_reason" in
|
|
2010
|
-
reconcile:*|acquire:acquire)
|
|
2011
|
-
rm -f "$agent_quota_dir/broker-reconcile-stale" 2>/dev/null || true
|
|
2012
|
-
;;
|
|
2013
|
-
esac
|
|
2014
|
-
unset budget_stale_signal budget_marker_reason
|
|
2015
|
-
}
|
|
2016
|
-
|
|
2017
|
-
# A reconcile failure is structural — broker predates the `reconcile`
|
|
2018
|
-
# subcommand, is older than the ledger's version stamp, cannot write to the
|
|
2019
|
-
# ledger, or cannot run at all — unless it is a transient SQLite lock that can
|
|
2020
|
-
# succeed on the next attempt. Distinguish by content, not by exit code: every
|
|
2021
|
-
# structural case must be surfaced once rather than silently swallowed on every
|
|
2022
|
-
# 304, and the argparse "invalid choice" wording is deliberately not matched
|
|
2023
|
-
# (it is not a stability contract across Python versions; the trigger and stamp
|
|
2024
|
-
# messages above are this project's own).
|
|
2025
|
-
budget_reconcile_transient() {
|
|
2026
|
-
# $1 is the broker's merged output, $2 its exit status. A SLOW broker is not a
|
|
2027
|
-
# STALE one, and only staleness may raise the fleet alert: a `reconcile`-reason
|
|
2028
|
-
# marker is cleared by nothing but a later successful reconcile, so misreading
|
|
2029
|
-
# one transient fault as structural latches a permanent alert on a healthy
|
|
2030
|
-
# workspace. Death by signal (128+N — an OOM kill, a supervisor SIGKILL, a
|
|
2031
|
-
# SIGTERM at shutdown) and a non-zero exit with no output at all are both the
|
|
2032
|
-
# shape of an interrupted broker, not one that predates the ledger schema.
|
|
2033
|
-
# #2457 shows those faults are live: 28 broker timeouts in ten minutes after a
|
|
2034
|
-
# single daemon restart. Every structural failure still prints something —
|
|
2035
|
-
# argparse usage, the trigger/stamp refusal, `python3: not found`, a traceback
|
|
2036
|
-
# — so it stays on the loud path.
|
|
2037
|
-
case "$2" in
|
|
2038
|
-
12[89]|1[3-9][0-9]|2[0-9][0-9])
|
|
2039
|
-
return 0
|
|
2040
|
-
;;
|
|
2041
|
-
esac
|
|
2042
|
-
[ -n "$1" ] || return 0
|
|
2043
|
-
case "$1" in
|
|
2044
|
-
*"database is locked"*|*"database table is locked"*)
|
|
2045
|
-
return 0
|
|
2046
|
-
;;
|
|
2047
|
-
esac
|
|
2048
|
-
return 1
|
|
2049
|
-
}
|
|
2050
|
-
|
|
2051
|
-
budget_reconcile_response() {
|
|
2052
|
-
[ "$budget_enabled" -eq 1 ] || return 0
|
|
2053
|
-
[ -n "$budget_lease" ] || return 0
|
|
2054
|
-
[ -n "$output_file" ] && [ -f "$output_file" ] || return 0
|
|
2055
|
-
|
|
2056
|
-
if awk '/^HTTP\/[^[:space:]]+[[:space:]]+[0-9][0-9][0-9]/ { status = $2 } END { exit status == 304 ? 0 : 1 }' "$output_file"; then
|
|
2057
|
-
if budget_reconcile_output=$(budget_command reconcile --lease-id "$budget_lease" --status 304 2>&1); then
|
|
2058
|
-
# Reconcile succeeded: a refreshed broker has recovered, so clear any
|
|
2059
|
-
# stale-broker marker left by an earlier structural failure.
|
|
2060
|
-
budget_clear_stale_broker reconcile
|
|
2061
|
-
else
|
|
2062
|
-
budget_reconcile_status=$?
|
|
2063
|
-
|
|
2064
|
-
if ! budget_reconcile_transient "$budget_reconcile_output" "$budget_reconcile_status"; then
|
|
2065
|
-
budget_mark_stale_broker reconcile
|
|
2066
|
-
fi
|
|
2067
|
-
fi
|
|
2068
|
-
fi
|
|
2069
|
-
unset budget_reconcile_output budget_reconcile_status
|
|
2070
|
-
}
|
|
2071
|
-
|
|
2072
|
-
# 304 reconciliation for high-level commands. `gh` only exposes the HTTP status
|
|
2073
|
-
# under `GH_DEBUG=api`, so the guarded run above captured it in `$error_file` as
|
|
2074
|
-
# `< HTTP/... <status>` lines. A high-level command can issue several HTTP
|
|
2075
|
-
# requests under one lease (`gh pr view` resolves the repo through git
|
|
2076
|
-
# subprocesses and then makes one or more API requests), so the reconcile fires
|
|
2077
|
-
# only when EVERY observed status is 304 — a single 304 among 200s must not
|
|
2078
|
-
# mark the whole lease free, which under-reported spend whenever a 200 preceded
|
|
2079
|
-
# a 304 (#2353 review). Then the whole debug transcript is stripped so every
|
|
2080
|
-
# later consumer (rate-limit classification, stderr replay) sees only the real
|
|
2081
|
-
# stderr. A command that produced no debug (budget disabled, no request, a
|
|
2082
|
-
# caller that already set its own debug) is a no-op here.
|
|
2083
|
-
budget_reconcile_debug() {
|
|
2084
|
-
[ "$budget_enabled" -eq 1 ] || return 0
|
|
2085
|
-
[ -n "$budget_lease" ] || return 0
|
|
2086
|
-
[ -n "$error_file" ] && [ -f "$error_file" ] || return 0
|
|
2087
|
-
|
|
2088
|
-
debug_statuses=$(sed -n -E 's/^< HTTP\/[^[:space:]]+[[:space:]]+([0-9]{3}).*/\1/p' "$error_file")
|
|
2089
|
-
all_304=1
|
|
2090
|
-
case "$debug_statuses" in
|
|
2091
|
-
'') all_304=0 ;;
|
|
2092
|
-
*)
|
|
2093
|
-
for debug_status in $debug_statuses; do
|
|
2094
|
-
case "$debug_status" in
|
|
2095
|
-
304) ;;
|
|
2096
|
-
*) all_304=0; break ;;
|
|
2097
|
-
esac
|
|
2098
|
-
done
|
|
2099
|
-
;;
|
|
2100
|
-
esac
|
|
2101
|
-
if [ "$all_304" -eq 1 ]; then
|
|
2102
|
-
budget_command reconcile --lease-id "$budget_lease" --status 304 >/dev/null 2>&1 || true
|
|
2103
|
-
fi
|
|
2104
|
-
unset all_304 debug_statuses debug_status
|
|
2105
|
-
|
|
2106
|
-
strip_gh_debug "$error_file"
|
|
2107
|
-
return 0
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
# Drops `GH_DEBUG=api`'s transcript from a stderr capture, keeping only what
|
|
2111
|
-
# gh printed outside it (pre-request warnings and post-request errors). The
|
|
2112
|
-
# transcript is contiguous: every debug line between the request's start and
|
|
2113
|
-
# its `Request took` marker — request headers, request body, response headers,
|
|
2114
|
-
# response body — is removed, and the `[git ...]` subprocess lines `gh` prints
|
|
2115
|
-
# BEFORE the first request marker are dropped too (they are part of the debug
|
|
2116
|
-
# transcript, not caller-facing stderr), so the caller's stderr and the error
|
|
2117
|
-
# classifiers see exactly what they saw before high-level debug was enabled.
|
|
2118
|
-
strip_gh_debug() {
|
|
2119
|
-
[ -f "$1" ] || return 0
|
|
2120
|
-
strip_tmp="$1.dbg.$$"
|
|
2121
|
-
if awk '
|
|
2122
|
-
/^\* Request at / { in_debug = 1; next }
|
|
2123
|
-
in_debug && /^\* Request took / { in_debug = 0; next }
|
|
2124
|
-
!in_debug && /^\[git / { next }
|
|
2125
|
-
!in_debug { print }
|
|
2126
|
-
' "$1" > "$strip_tmp" 2>/dev/null; then
|
|
2127
|
-
mv -f "$strip_tmp" "$1" 2>/dev/null || rm -f "$strip_tmp" 2>/dev/null || true
|
|
2128
|
-
else
|
|
2129
|
-
rm -f "$strip_tmp" 2>/dev/null || true
|
|
2130
|
-
fi
|
|
2131
|
-
unset strip_tmp
|
|
2132
|
-
return 0
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
budget_start_renewal() {
|
|
2136
|
-
[ -n "$budget_lease" ] || return 0
|
|
2137
|
-
budget_renew_interval=$((budget_lease_ttl_ms / 3 / 1000))
|
|
2138
|
-
[ "$budget_renew_interval" -gt 0 ] || budget_renew_interval=1
|
|
2139
|
-
|
|
2140
|
-
(
|
|
2141
|
-
while sleep "$budget_renew_interval"; do
|
|
2142
|
-
budget_command renew --lease-id "$budget_lease" --lease-ttl-ms "$budget_lease_ttl_ms" >/dev/null 2>&1 || exit 0
|
|
2143
|
-
done
|
|
2144
|
-
) >/dev/null 2>&1 &
|
|
2145
|
-
budget_renewal_pid=$!
|
|
2146
|
-
unset budget_renew_interval
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
budget_hold() {
|
|
2150
|
-
budget_scope=$1
|
|
2151
|
-
budget_delay=$2
|
|
2152
|
-
budget_resource=${3:-$resource}
|
|
2153
|
-
[ "$budget_enabled" -eq 1 ] || return 0
|
|
2154
|
-
budget_command hold --scope "$budget_scope" --resource "$budget_resource" --delay-ms "$budget_delay" >/dev/null 2>&1 || true
|
|
2155
|
-
}
|
|
2156
|
-
|
|
2157
|
-
# `gh api --paginate` normally makes its follow-up requests inside one gh
|
|
2158
|
-
# process. Re-enter this guard for each REST page instead, so every network
|
|
2159
|
-
# request obtains and releases its own shared broker lease. The child is also
|
|
2160
|
-
# responsible for response observation and quota tracking; it has no
|
|
2161
|
-
# `--paginate` flag, so it follows the ordinary single-request path.
|
|
2162
|
-
run_budgeted_paginated_api() {
|
|
2163
|
-
AIUR_GITHUB_PAGINATION_WRAPPER="$0" AIUR_GITHUB_PAGINATION_REAL_GH="$real_gh" AIUR_GITHUB_PAGINATION_DIRECTION="$direction" python3 - "$@" <<'PY'
|
|
2164
|
-
import http.server
|
|
2165
|
-
import json
|
|
2166
|
-
import os
|
|
2167
|
-
import re
|
|
2168
|
-
import shutil
|
|
2169
|
-
import subprocess
|
|
2170
|
-
import sys
|
|
2171
|
-
import threading
|
|
2172
|
-
from urllib.parse import urlsplit
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
def split_response(output):
|
|
2176
|
-
match = re.search(br"\r?\n\r?\n", output)
|
|
2177
|
-
if match is None:
|
|
2178
|
-
return b"", output
|
|
2179
|
-
return output[: match.start()], output[match.end() :]
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
def next_endpoint(headers):
|
|
2183
|
-
for line in headers.decode("utf-8", "replace").splitlines():
|
|
2184
|
-
if not line.lower().startswith("link:"):
|
|
2185
|
-
continue
|
|
2186
|
-
match = re.search(r'<([^>]+)>;\s*rel="next"', line, re.IGNORECASE)
|
|
2187
|
-
if match is None:
|
|
2188
|
-
continue
|
|
2189
|
-
parsed = urlsplit(match.group(1))
|
|
2190
|
-
endpoint = parsed.path or "/"
|
|
2191
|
-
return f"{endpoint}?{parsed.query}" if parsed.query else endpoint
|
|
2192
|
-
return None
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
def next_cursor(body):
|
|
2196
|
-
try:
|
|
2197
|
-
response = json.loads(body)
|
|
2198
|
-
except json.JSONDecodeError:
|
|
2199
|
-
print("aiur: gh api GraphQL pagination returned a non-JSON page", file=sys.stderr)
|
|
2200
|
-
raise SystemExit(1)
|
|
2201
|
-
|
|
2202
|
-
stack = [response]
|
|
2203
|
-
while stack:
|
|
2204
|
-
value = stack.pop()
|
|
2205
|
-
if isinstance(value, dict):
|
|
2206
|
-
if {"hasNextPage", "endCursor"} <= value.keys():
|
|
2207
|
-
if not value["hasNextPage"]:
|
|
2208
|
-
return None
|
|
2209
|
-
cursor = value["endCursor"]
|
|
2210
|
-
if isinstance(cursor, str) and cursor:
|
|
2211
|
-
return cursor
|
|
2212
|
-
print("aiur: gh api GraphQL pagination returned an invalid endCursor", file=sys.stderr)
|
|
2213
|
-
raise SystemExit(1)
|
|
2214
|
-
stack.extend(value.values())
|
|
2215
|
-
elif isinstance(value, list):
|
|
2216
|
-
stack.extend(value)
|
|
2217
|
-
|
|
2218
|
-
print("aiur: gh api GraphQL pagination response is missing pageInfo", file=sys.stderr)
|
|
2219
|
-
raise SystemExit(1)
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
def endpoint_index(args):
|
|
2223
|
-
value_flags = {
|
|
2224
|
-
"--cache", "-F", "--field", "-f", "--raw-field", "-H", "--header",
|
|
2225
|
-
"--hostname", "--input", "-q", "--jq", "-X", "--method", "-p",
|
|
2226
|
-
"--preview", "-t", "--template",
|
|
2227
|
-
}
|
|
2228
|
-
awaiting_value = False
|
|
2229
|
-
|
|
2230
|
-
for index, arg in enumerate(args[1:], start=1):
|
|
2231
|
-
if awaiting_value:
|
|
2232
|
-
awaiting_value = False
|
|
2233
|
-
continue
|
|
2234
|
-
if arg == "--":
|
|
2235
|
-
return index + 1 if index + 1 < len(args) else None
|
|
2236
|
-
if arg in value_flags:
|
|
2237
|
-
awaiting_value = True
|
|
2238
|
-
continue
|
|
2239
|
-
if arg in {"--include", "-i", "--silent", "--verbose"}:
|
|
2240
|
-
continue
|
|
2241
|
-
if arg.startswith("--"):
|
|
2242
|
-
continue
|
|
2243
|
-
if arg.startswith("-"):
|
|
2244
|
-
if arg[:2] in {"-F", "-f", "-H", "-q", "-X", "-p", "-t"} and len(arg) > 2:
|
|
2245
|
-
continue
|
|
2246
|
-
return None
|
|
2247
|
-
return index
|
|
2248
|
-
|
|
2249
|
-
return None
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
def active_flag(args, *values):
|
|
2253
|
-
options = True
|
|
2254
|
-
|
|
2255
|
-
for arg in args:
|
|
2256
|
-
if options and arg == "--":
|
|
2257
|
-
options = False
|
|
2258
|
-
elif options and (arg in values or any(value.startswith("--") and arg == f"{value}=true" for value in values)):
|
|
2259
|
-
return True
|
|
2260
|
-
|
|
2261
|
-
return False
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
def without_pagination_flags(args):
|
|
2265
|
-
page_args = []
|
|
2266
|
-
options = True
|
|
2267
|
-
|
|
2268
|
-
for arg in args:
|
|
2269
|
-
if options and arg == "--":
|
|
2270
|
-
options = False
|
|
2271
|
-
if options and arg in {"--paginate", "--paginate=true", "--slurp", "--slurp=true"}:
|
|
2272
|
-
continue
|
|
2273
|
-
page_args.append(arg)
|
|
2274
|
-
|
|
2275
|
-
return page_args
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
def extract_output_formatter(args):
|
|
2279
|
-
"""Keep one unformatted request per page and retain gh's formatter args."""
|
|
2280
|
-
|
|
2281
|
-
page_args = []
|
|
2282
|
-
formatter = None
|
|
2283
|
-
index = 0
|
|
2284
|
-
options = True
|
|
2285
|
-
|
|
2286
|
-
while index < len(args):
|
|
2287
|
-
arg = args[index]
|
|
2288
|
-
if options and arg == "--":
|
|
2289
|
-
options = False
|
|
2290
|
-
page_args.extend(args[index:])
|
|
2291
|
-
break
|
|
2292
|
-
|
|
2293
|
-
kind = None
|
|
2294
|
-
expression = None
|
|
2295
|
-
if options and arg in {"-q", "--jq", "-t", "--template"}:
|
|
2296
|
-
if index + 1 >= len(args):
|
|
2297
|
-
print(f"aiur: {arg} requires an output expression", file=sys.stderr)
|
|
2298
|
-
raise SystemExit(64)
|
|
2299
|
-
kind = "jq" if arg in {"-q", "--jq"} else "template"
|
|
2300
|
-
expression = args[index + 1]
|
|
2301
|
-
index += 2
|
|
2302
|
-
elif options and arg.startswith("--jq="):
|
|
2303
|
-
kind, expression = "jq", arg.split("=", 1)[1]
|
|
2304
|
-
index += 1
|
|
2305
|
-
elif options and arg.startswith("--template="):
|
|
2306
|
-
kind, expression = "template", arg.split("=", 1)[1]
|
|
2307
|
-
index += 1
|
|
2308
|
-
elif options and arg.startswith("-q") and len(arg) > 2:
|
|
2309
|
-
kind, expression = "jq", arg[2:]
|
|
2310
|
-
index += 1
|
|
2311
|
-
elif options and arg.startswith("-t") and len(arg) > 2:
|
|
2312
|
-
kind, expression = "template", arg[2:]
|
|
2313
|
-
index += 1
|
|
2314
|
-
else:
|
|
2315
|
-
page_args.append(arg)
|
|
2316
|
-
index += 1
|
|
2317
|
-
continue
|
|
2318
|
-
|
|
2319
|
-
if formatter is not None:
|
|
2320
|
-
print("aiur: gh api accepts only one output formatter", file=sys.stderr)
|
|
2321
|
-
raise SystemExit(64)
|
|
2322
|
-
formatter = (kind, expression)
|
|
2323
|
-
|
|
2324
|
-
return page_args, formatter
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
def paginated_request_uses_input(args):
|
|
2328
|
-
value_flags = {"-F", "--field", "-f", "--raw-field"}
|
|
2329
|
-
|
|
2330
|
-
for index, arg in enumerate(args):
|
|
2331
|
-
if arg == "--input" or arg.startswith("--input="):
|
|
2332
|
-
return True
|
|
2333
|
-
if arg in value_flags and index + 1 < len(args):
|
|
2334
|
-
value = args[index + 1]
|
|
2335
|
-
if "=@" in value:
|
|
2336
|
-
return True
|
|
2337
|
-
if "=@" in arg and (
|
|
2338
|
-
arg.startswith(("-F", "-f")) or arg.startswith(("--field=", "--raw-field="))
|
|
2339
|
-
):
|
|
2340
|
-
return True
|
|
2341
|
-
|
|
2342
|
-
return False
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
def add_include(args):
|
|
2346
|
-
if active_flag(args, "--include", "-i"):
|
|
2347
|
-
return args
|
|
2348
|
-
|
|
2349
|
-
page_args = args.copy()
|
|
2350
|
-
try:
|
|
2351
|
-
page_args.insert(page_args.index("--"), "--include")
|
|
2352
|
-
except ValueError:
|
|
2353
|
-
page_args.append("--include")
|
|
2354
|
-
return page_args
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
def formatter_arguments(formatter):
|
|
2358
|
-
kind, expression = formatter
|
|
2359
|
-
return ["--jq" if kind == "jq" else "--template", expression]
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
def response_status(headers):
|
|
2363
|
-
match = re.search(br"^HTTP/[^\s]+\s+(\d{3})", headers)
|
|
2364
|
-
return int(match.group(1)) if match else 200
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
def response_headers(headers):
|
|
2368
|
-
for line in headers.splitlines()[1:]:
|
|
2369
|
-
if b":" not in line:
|
|
2370
|
-
continue
|
|
2371
|
-
name, value = line.split(b":", 1)
|
|
2372
|
-
name = name.decode("latin-1")
|
|
2373
|
-
if name.lower() in {"connection", "content-length", "link", "transfer-encoding"}:
|
|
2374
|
-
continue
|
|
2375
|
-
yield name, value.decode("latin-1").strip()
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
def response_header_values(headers, name):
|
|
2379
|
-
prefix = name.lower().encode("ascii") + b":"
|
|
2380
|
-
return [line for line in headers.splitlines()[1:] if line.lower().startswith(prefix)]
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
def linux_process_owns_connection(pid, client_port, server_port):
|
|
2384
|
-
"""Verify the renderer owns the client side of this loopback connection."""
|
|
2385
|
-
|
|
2386
|
-
inode = None
|
|
2387
|
-
try:
|
|
2388
|
-
with open("/proc/net/tcp", encoding="ascii") as connections:
|
|
2389
|
-
for line in connections.readlines()[1:]:
|
|
2390
|
-
fields = line.split()
|
|
2391
|
-
local_port = int(fields[1].rsplit(":", 1)[1], 16)
|
|
2392
|
-
remote_port = int(fields[2].rsplit(":", 1)[1], 16)
|
|
2393
|
-
if fields[3] == "01" and local_port == client_port and remote_port == server_port:
|
|
2394
|
-
inode = fields[9]
|
|
2395
|
-
break
|
|
2396
|
-
except (FileNotFoundError, OSError, ValueError, IndexError):
|
|
2397
|
-
return False
|
|
2398
|
-
|
|
2399
|
-
if inode is None:
|
|
2400
|
-
return False
|
|
2401
|
-
|
|
2402
|
-
expected = f"socket:[{inode}]"
|
|
2403
|
-
try:
|
|
2404
|
-
file_descriptors = os.listdir(f"/proc/{pid}/fd")
|
|
2405
|
-
except (FileNotFoundError, OSError):
|
|
2406
|
-
return False
|
|
2407
|
-
|
|
2408
|
-
for fd in file_descriptors:
|
|
2409
|
-
try:
|
|
2410
|
-
if os.readlink(f"/proc/{pid}/fd/{fd}") == expected:
|
|
2411
|
-
return True
|
|
2412
|
-
except (FileNotFoundError, OSError):
|
|
2413
|
-
continue
|
|
2414
|
-
return False
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
def darwin_process_owns_connection(pid, client_port, server_port):
|
|
2418
|
-
"""Use macOS's system lsof to bind the replay to the renderer process."""
|
|
2419
|
-
|
|
2420
|
-
lsof = shutil.which("lsof")
|
|
2421
|
-
if lsof is None and os.path.isfile("/usr/sbin/lsof"):
|
|
2422
|
-
lsof = "/usr/sbin/lsof"
|
|
2423
|
-
if lsof is None:
|
|
2424
|
-
return False
|
|
2425
|
-
|
|
2426
|
-
try:
|
|
2427
|
-
result = subprocess.run(
|
|
2428
|
-
[lsof, "-nP", "-a", "-p", str(pid), "-iTCP"],
|
|
2429
|
-
stdout=subprocess.PIPE,
|
|
2430
|
-
stderr=subprocess.DEVNULL,
|
|
2431
|
-
text=True,
|
|
2432
|
-
timeout=5,
|
|
2433
|
-
)
|
|
2434
|
-
except (OSError, subprocess.TimeoutExpired):
|
|
2435
|
-
return False
|
|
2436
|
-
connection = f"127.0.0.1:{client_port}->127.0.0.1:{server_port}"
|
|
2437
|
-
return result.returncode == 0 and connection in result.stdout
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
def process_owns_connection(pid, client_port, server_port):
|
|
2441
|
-
if sys.platform.startswith("linux"):
|
|
2442
|
-
return linux_process_owns_connection(pid, client_port, server_port)
|
|
2443
|
-
if sys.platform == "darwin":
|
|
2444
|
-
return darwin_process_owns_connection(pid, client_port, server_port)
|
|
2445
|
-
return False
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
def render_with_native_gh(formatter, captured_pages, slurp, include_headers):
|
|
2449
|
-
"""Replay admitted responses locally and let gh render them unchanged.
|
|
2450
|
-
|
|
2451
|
-
Calling gh once more against GitHub would bypass the captured page's lease.
|
|
2452
|
-
A loopback replay keeps the formatter in gh itself (including its embedded
|
|
2453
|
-
jq, Go-template helpers, and table state) without another GitHub request.
|
|
2454
|
-
"""
|
|
2455
|
-
|
|
2456
|
-
if slurp:
|
|
2457
|
-
try:
|
|
2458
|
-
payload = json.dumps([json.loads(body) for _headers, body in captured_pages]).encode("utf-8")
|
|
2459
|
-
except json.JSONDecodeError:
|
|
2460
|
-
print("aiur: gh api --paginate --slurp returned a non-JSON page", file=sys.stderr)
|
|
2461
|
-
raise SystemExit(1)
|
|
2462
|
-
replay_pages = [(b"", payload)]
|
|
2463
|
-
paginate = False
|
|
2464
|
-
else:
|
|
2465
|
-
replay_pages = captured_pages
|
|
2466
|
-
paginate = True
|
|
2467
|
-
|
|
2468
|
-
class ReplayHandler(http.server.BaseHTTPRequestHandler):
|
|
2469
|
-
protocol_version = "HTTP/1.1"
|
|
2470
|
-
|
|
2471
|
-
def do_GET(self):
|
|
2472
|
-
self.server.renderer_ready.wait(timeout=5)
|
|
2473
|
-
renderer_pid = self.server.renderer_pid
|
|
2474
|
-
if renderer_pid is None or not process_owns_connection(
|
|
2475
|
-
renderer_pid, self.client_address[1], self.server.server_port
|
|
2476
|
-
):
|
|
2477
|
-
self.send_error(403)
|
|
2478
|
-
return
|
|
2479
|
-
|
|
2480
|
-
match = re.fullmatch(r"/(\d+)", self.path.split("?", 1)[0])
|
|
2481
|
-
page = int(match.group(1)) if match else -1
|
|
2482
|
-
if not 0 <= page < len(replay_pages):
|
|
2483
|
-
self.send_error(404)
|
|
2484
|
-
return
|
|
2485
|
-
|
|
2486
|
-
headers, body = replay_pages[page]
|
|
2487
|
-
self.send_response(response_status(headers))
|
|
2488
|
-
content_type = False
|
|
2489
|
-
for name, value in response_headers(headers):
|
|
2490
|
-
content_type = content_type or name.lower() == "content-type"
|
|
2491
|
-
self.send_header(name, value)
|
|
2492
|
-
if not content_type:
|
|
2493
|
-
self.send_header("Content-Type", "application/json")
|
|
2494
|
-
if page + 1 < len(replay_pages):
|
|
2495
|
-
self.send_header("Link", f"<http://127.0.0.1:{self.server.server_port}/{page + 1}>; rel=\"next\"")
|
|
2496
|
-
self.send_header("Content-Length", str(len(body)))
|
|
2497
|
-
self.end_headers()
|
|
2498
|
-
self.wfile.write(body)
|
|
2499
|
-
|
|
2500
|
-
def send_response(self, code, message=None):
|
|
2501
|
-
# Preserve captured response headers instead of adding the replay
|
|
2502
|
-
# server's own Server and Date headers to --include output.
|
|
2503
|
-
self.send_response_only(code, message)
|
|
2504
|
-
|
|
2505
|
-
def log_message(self, _format, *_args):
|
|
2506
|
-
pass
|
|
2507
|
-
|
|
2508
|
-
server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), ReplayHandler)
|
|
2509
|
-
server.daemon_threads = True
|
|
2510
|
-
server.block_on_close = False
|
|
2511
|
-
server.renderer_pid = None
|
|
2512
|
-
server.renderer_ready = threading.Event()
|
|
2513
|
-
thread = threading.Thread(target=server.serve_forever, daemon=True)
|
|
2514
|
-
thread.start()
|
|
2515
|
-
try:
|
|
2516
|
-
command = [os.environ["AIUR_GITHUB_PAGINATION_REAL_GH"], "api", f"http://127.0.0.1:{server.server_port}/0"]
|
|
2517
|
-
if paginate:
|
|
2518
|
-
command.append("--paginate")
|
|
2519
|
-
if include_headers:
|
|
2520
|
-
command.append("--include")
|
|
2521
|
-
command.extend(formatter_arguments(formatter))
|
|
2522
|
-
environment = os.environ.copy()
|
|
2523
|
-
for name in ("GH_TOKEN", "GITHUB_TOKEN", "GH_ENTERPRISE_TOKEN", "GITHUB_ENTERPRISE_TOKEN"):
|
|
2524
|
-
environment.pop(name, None)
|
|
2525
|
-
# gh requires an authentication source before it will issue even an
|
|
2526
|
-
# absolute loopback request. Replace inherited credentials with a
|
|
2527
|
-
# fixed non-secret accepted only by this renderer-bound local server.
|
|
2528
|
-
environment["GH_TOKEN"] = "aiur-local-replay"
|
|
2529
|
-
environment["NO_PROXY"] = "127.0.0.1,localhost"
|
|
2530
|
-
environment["no_proxy"] = "127.0.0.1,localhost"
|
|
2531
|
-
capture_headers = include_headers and paginate
|
|
2532
|
-
process = subprocess.Popen(command, env=environment, stdout=subprocess.PIPE if capture_headers else None)
|
|
2533
|
-
server.renderer_pid = process.pid
|
|
2534
|
-
server.renderer_ready.set()
|
|
2535
|
-
rendered, _stderr = process.communicate()
|
|
2536
|
-
|
|
2537
|
-
if capture_headers:
|
|
2538
|
-
for page, (headers, _body) in enumerate(replay_pages[:-1]):
|
|
2539
|
-
local = f'Link: <http://127.0.0.1:{server.server_port}/{page + 1}>; rel="next"'.encode("ascii")
|
|
2540
|
-
original = b"\n".join(response_header_values(headers, "Link"))
|
|
2541
|
-
rendered = rendered.replace(local, original)
|
|
2542
|
-
sys.stdout.buffer.write(rendered)
|
|
2543
|
-
|
|
2544
|
-
return process.returncode
|
|
2545
|
-
finally:
|
|
2546
|
-
server.shutdown()
|
|
2547
|
-
thread.join()
|
|
2548
|
-
server.server_close()
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
args = sys.argv[1:]
|
|
2552
|
-
include_headers = active_flag(args, "--include", "-i")
|
|
2553
|
-
slurp = active_flag(args, "--slurp")
|
|
2554
|
-
silent = active_flag(args, "--silent")
|
|
2555
|
-
verbose = active_flag(args, "--verbose")
|
|
2556
|
-
display_args = without_pagination_flags(args)
|
|
2557
|
-
raw_args, formatter = extract_output_formatter(display_args)
|
|
2558
|
-
|
|
2559
|
-
if formatter and (silent or verbose):
|
|
2560
|
-
print("only one of `--template`, `--jq`, `--silent`, or `--verbose` may be used", file=sys.stderr)
|
|
2561
|
-
raise SystemExit(1)
|
|
2562
|
-
|
|
2563
|
-
raw_args = add_include(raw_args)
|
|
2564
|
-
raw_endpoint_index = endpoint_index(raw_args)
|
|
2565
|
-
|
|
2566
|
-
if raw_endpoint_index is None or raw_args[0] != "api":
|
|
2567
|
-
print("aiur: cannot budget malformed gh api pagination command", file=sys.stderr)
|
|
2568
|
-
raise SystemExit(64)
|
|
2569
|
-
|
|
2570
|
-
if paginated_request_uses_input(raw_args):
|
|
2571
|
-
print("aiur: cannot budget gh api --paginate commands that use an input body or standard input", file=sys.stderr)
|
|
2572
|
-
raise SystemExit(64)
|
|
2573
|
-
|
|
2574
|
-
if os.environ.get("AIUR_GITHUB_PAGINATION_DIRECTION") == "write":
|
|
2575
|
-
print("aiur: cannot budget a paginated write", file=sys.stderr)
|
|
2576
|
-
raise SystemExit(64)
|
|
2577
|
-
|
|
2578
|
-
wrapper = os.environ["AIUR_GITHUB_PAGINATION_WRAPPER"]
|
|
2579
|
-
pages = []
|
|
2580
|
-
captured_pages = []
|
|
2581
|
-
graphql = raw_args[raw_endpoint_index] in {"graphql", "/graphql"}
|
|
2582
|
-
|
|
2583
|
-
raw_cursor_arg_index = next(
|
|
2584
|
-
(
|
|
2585
|
-
index
|
|
2586
|
-
for index, arg in enumerate(raw_args)
|
|
2587
|
-
if index > 0
|
|
2588
|
-
and arg.startswith("endCursor=")
|
|
2589
|
-
and raw_args[index - 1] in {"-F", "--field", "-f", "--raw-field"}
|
|
2590
|
-
),
|
|
2591
|
-
None,
|
|
2592
|
-
)
|
|
2593
|
-
|
|
2594
|
-
while True:
|
|
2595
|
-
result = subprocess.run([wrapper, *raw_args], stdout=subprocess.PIPE)
|
|
2596
|
-
headers, body = split_response(result.stdout)
|
|
2597
|
-
|
|
2598
|
-
if result.returncode:
|
|
2599
|
-
if not silent:
|
|
2600
|
-
if include_headers:
|
|
2601
|
-
sys.stdout.buffer.write(headers)
|
|
2602
|
-
if headers:
|
|
2603
|
-
sys.stdout.buffer.write(b"\n\n")
|
|
2604
|
-
sys.stdout.buffer.write(body)
|
|
2605
|
-
raise SystemExit(result.returncode)
|
|
2606
|
-
|
|
2607
|
-
if silent:
|
|
2608
|
-
pass
|
|
2609
|
-
elif formatter:
|
|
2610
|
-
captured_pages.append((headers, body))
|
|
2611
|
-
elif slurp:
|
|
2612
|
-
try:
|
|
2613
|
-
pages.append(json.loads(body))
|
|
2614
|
-
except json.JSONDecodeError:
|
|
2615
|
-
print("aiur: gh api --paginate --slurp returned a non-JSON page", file=sys.stderr)
|
|
2616
|
-
raise SystemExit(1)
|
|
2617
|
-
else:
|
|
2618
|
-
if include_headers:
|
|
2619
|
-
sys.stdout.buffer.write(headers)
|
|
2620
|
-
if headers:
|
|
2621
|
-
sys.stdout.buffer.write(b"\n\n")
|
|
2622
|
-
sys.stdout.buffer.write(body)
|
|
2623
|
-
|
|
2624
|
-
if graphql:
|
|
2625
|
-
cursor = next_cursor(body)
|
|
2626
|
-
if cursor is None:
|
|
2627
|
-
break
|
|
2628
|
-
if raw_cursor_arg_index is None:
|
|
2629
|
-
raw_args.extend(["-F", f"endCursor={cursor}"])
|
|
2630
|
-
raw_cursor_arg_index = len(raw_args) - 1
|
|
2631
|
-
else:
|
|
2632
|
-
raw_args[raw_cursor_arg_index] = f"endCursor={cursor}"
|
|
2633
|
-
else:
|
|
2634
|
-
endpoint = next_endpoint(headers)
|
|
2635
|
-
if endpoint is None:
|
|
2636
|
-
break
|
|
2637
|
-
raw_args[raw_endpoint_index] = endpoint
|
|
2638
|
-
|
|
2639
|
-
if formatter:
|
|
2640
|
-
raise SystemExit(render_with_native_gh(formatter, captured_pages, slurp, include_headers))
|
|
2641
|
-
|
|
2642
|
-
if slurp:
|
|
2643
|
-
payload = json.dumps(pages).encode("utf-8")
|
|
2644
|
-
if not silent:
|
|
2645
|
-
sys.stdout.buffer.write(payload)
|
|
2646
|
-
sys.stdout.buffer.write(b"\n")
|
|
2647
|
-
PY
|
|
2648
|
-
}
|
|
2649
|
-
|
|
2650
|
-
trap 'budget_release; exit 143' HUP INT TERM
|
|
2651
|
-
trap 'budget_release' 0
|
|
2652
|
-
|
|
2653
|
-
secondary_delay_ms() {
|
|
2654
|
-
retry_after=
|
|
2655
|
-
for retry_source in "$@"; do
|
|
2656
|
-
[ -n "$retry_source" ] && [ -f "$retry_source" ] || continue
|
|
2657
|
-
retry_after=$(sed -n -E 's/^[[:space:]]*[Rr][Ee][Tt][Rr][Yy]-[Aa][Ff][Tt][Ee][Rr]:[[:space:]]*([0-9]+).*/\1/p' "$retry_source" | sed -n '1p')
|
|
2658
|
-
[ -n "$retry_after" ] && break
|
|
2659
|
-
done
|
|
2660
|
-
|
|
2661
|
-
case "$retry_after" in
|
|
2662
|
-
''|0|*[!0-9]*) printf '%s\n' 60000 ;;
|
|
2663
|
-
*)
|
|
2664
|
-
if [ "$retry_after" -gt 3600 ]; then retry_after=3600; fi
|
|
2665
|
-
printf '%s\n' $((retry_after * 1000))
|
|
2666
|
-
;;
|
|
2667
|
-
esac
|
|
2668
|
-
}
|
|
2669
|
-
|
|
2670
|
-
# Reuse the timestamp the cache section already sampled rather than forking
|
|
2671
|
-
# `date` a second time; they are the same instant for every purpose here.
|
|
2672
|
-
now=${cache_started_at:-}
|
|
2673
|
-
case "$now" in
|
|
2674
|
-
''|*[!0-9]*) now=$(date -u +%s) ;;
|
|
2675
|
-
esac
|
|
2676
|
-
hold_until=0
|
|
2677
|
-
|
|
2678
|
-
# A truncating `>` redirect leaves the hold file empty between truncate and
|
|
2679
|
-
# write. A concurrent reader sampling it in that gap sees no hold, `consider_hold`
|
|
2680
|
-
# bails, and the call goes out during an exhausted window. Writing to a sibling
|
|
2681
|
-
# temp file and renaming makes the hold appear in one step — the same reason the
|
|
2682
|
-
# Elixir side uses temp+rename in `Aiur.AgentGitHubGuard.write_hold_file/3`.
|
|
2683
|
-
write_hold() {
|
|
2684
|
-
write_hold_tmp="$1.tmp.$$"
|
|
2685
|
-
|
|
2686
|
-
if printf '%s\n' "$2" > "$write_hold_tmp" 2>/dev/null; then
|
|
2687
|
-
mv -f "$write_hold_tmp" "$1" 2>/dev/null || rm -f "$write_hold_tmp" 2>/dev/null || true
|
|
2688
|
-
else
|
|
2689
|
-
rm -f "$write_hold_tmp" 2>/dev/null || true
|
|
2690
|
-
fi
|
|
2691
|
-
|
|
2692
|
-
return 0
|
|
2693
|
-
}
|
|
2694
|
-
|
|
2695
|
-
# Exhaustion an agent discovers first is fleet-wide news, but holds used to be
|
|
2696
|
-
# written only to the per-workspace dir no other agent and not the daemon reads
|
|
2697
|
-
# — so everyone else rediscovered it on the daemon's next `/rate_limit` probe.
|
|
2698
|
-
# Reads already consult both dirs (`consider_resource_holds` below), so writes
|
|
2699
|
-
# publish to both too; an unwritable shared dir fails quietly and leaves the
|
|
2700
|
-
# workspace hold in place.
|
|
2701
|
-
publish_hold() {
|
|
2702
|
-
if [ -n "$agent_quota_dir" ]; then write_hold "$agent_quota_dir/$1" "$2"; fi
|
|
2703
|
-
|
|
2704
|
-
if [ -n "$quota_dir" ] && [ "$quota_dir" != "$agent_quota_dir" ]; then
|
|
2705
|
-
write_hold "$quota_dir/$1" "$2"
|
|
2706
|
-
fi
|
|
2707
|
-
|
|
2708
|
-
return 0
|
|
2709
|
-
}
|
|
2710
|
-
|
|
2711
|
-
consider_hold() {
|
|
2712
|
-
candidate=$(sed -n '1p' "$1" 2>/dev/null)
|
|
2713
|
-
case "$candidate" in
|
|
2714
|
-
''|*[!0-9]*) return ;;
|
|
2715
|
-
esac
|
|
2716
|
-
|
|
2717
|
-
if [ "$candidate" -gt "$now" ]; then
|
|
2718
|
-
if [ "$candidate" -gt "$hold_until" ]; then hold_until=$candidate; fi
|
|
2719
|
-
else
|
|
2720
|
-
rm -f "$1" 2>/dev/null || true
|
|
2721
|
-
fi
|
|
2722
|
-
}
|
|
2723
|
-
|
|
2724
|
-
# Both hold kinds gate a call: `-hold` is the exhausted primary window, and
|
|
2725
|
-
# `-secondary-hold` is a secondary/abuse-limit backoff, which GitHub raises
|
|
2726
|
-
# while the primary window still reads healthy.
|
|
2727
|
-
consider_resource_holds() {
|
|
2728
|
-
case "$2" in
|
|
2729
|
-
core|graphql|search)
|
|
2730
|
-
consider_hold "$1/$2-hold"
|
|
2731
|
-
consider_hold "$1/$2-secondary-hold"
|
|
2732
|
-
;;
|
|
2733
|
-
*)
|
|
2734
|
-
consider_hold "$1/core-hold"
|
|
2735
|
-
consider_hold "$1/core-secondary-hold"
|
|
2736
|
-
consider_hold "$1/graphql-hold"
|
|
2737
|
-
consider_hold "$1/graphql-secondary-hold"
|
|
2738
|
-
;;
|
|
2739
|
-
esac
|
|
2740
|
-
}
|
|
2741
|
-
|
|
2742
|
-
# The high-level list commands keep their own pagination loop inside one `gh`
|
|
2743
|
-
# process. A shell guard cannot admit those hidden HTTP pages individually, so
|
|
2744
|
-
# never let an invocation request more than one GitHub page under one lease.
|
|
2745
|
-
# `gh api --paginate` is handled above and remains the supported path for
|
|
2746
|
-
# callers that need more than GitHub's maximum 100-item page.
|
|
2747
|
-
native_page_limit_exceeds_single_request() {
|
|
2748
|
-
[ "${1:-}" != api ] || return 1
|
|
2749
|
-
|
|
2750
|
-
native_limit=
|
|
2751
|
-
native_expect_limit=0
|
|
2752
|
-
native_options=1
|
|
2753
|
-
|
|
2754
|
-
for native_argument in "$@"; do
|
|
2755
|
-
[ "$native_options" -eq 1 ] || continue
|
|
2756
|
-
|
|
2757
|
-
if [ "$native_expect_limit" -eq 1 ]; then
|
|
2758
|
-
native_limit=$native_argument
|
|
2759
|
-
native_expect_limit=0
|
|
2760
|
-
continue
|
|
2761
|
-
fi
|
|
2762
|
-
|
|
2763
|
-
case "$native_argument" in
|
|
2764
|
-
--) native_options=0 ;;
|
|
2765
|
-
--limit|-L) native_expect_limit=1 ;;
|
|
2766
|
-
--limit=*) native_limit=${native_argument#--limit=} ;;
|
|
2767
|
-
-L*) native_limit=${native_argument#-L} ;;
|
|
2768
|
-
esac
|
|
2769
|
-
done
|
|
2770
|
-
|
|
2771
|
-
case "$native_limit" in
|
|
2772
|
-
''|*[!0-9]*) return 1 ;;
|
|
2773
|
-
esac
|
|
2774
|
-
|
|
2775
|
-
[ "$native_limit" -gt "${AIUR_GITHUB_NATIVE_PAGE_SIZE:-100}" ]
|
|
2776
|
-
}
|
|
2777
|
-
|
|
2778
|
-
if [ "$resource" != none ] && [ "$budget_enabled" -eq 1 ] && native_page_limit_exceeds_single_request "$@"; then
|
|
2779
|
-
printf '%s\n' 'aiur: guarded high-level gh commands cannot fetch more than one page; use gh api --paginate for budgeted multi-page reads' >&2
|
|
2780
|
-
exit 64
|
|
2781
|
-
fi
|
|
2782
|
-
|
|
2783
|
-
if [ "$resource" != none ] && [ -n "$quota_dir" ]; then
|
|
2784
|
-
consider_resource_holds "$quota_dir" "$resource"
|
|
2785
|
-
fi
|
|
2786
|
-
|
|
2787
|
-
if [ "$resource" != none ] && [ -n "$agent_quota_dir" ] && [ "$agent_quota_dir" != "$quota_dir" ]; then
|
|
2788
|
-
consider_resource_holds "$agent_quota_dir" "$resource"
|
|
2789
|
-
fi
|
|
2790
|
-
|
|
2791
|
-
if [ "$hold_until" -gt "$now" ]; then
|
|
2792
|
-
delay=$((hold_until - now))
|
|
2793
|
-
printf 'aiur: GitHub quota backoff; waiting %ss until %s\n' "$delay" "$(date -u -d "@$hold_until" '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || printf '%s' "$hold_until")" >&2
|
|
2794
|
-
sleep "$delay"
|
|
2795
|
-
now=$(date -u +%s)
|
|
2796
|
-
fi
|
|
2797
|
-
|
|
2798
|
-
if [ "$admission_required" -eq 1 ]; then
|
|
2799
|
-
if [ "$api_paginated" -eq 1 ] && [ "$budget_enabled" -eq 1 ]; then
|
|
2800
|
-
run_budgeted_paginated_api "$@"
|
|
2801
|
-
exit $?
|
|
2802
|
-
fi
|
|
2803
|
-
budget_acquire
|
|
2804
|
-
budget_admission=$?
|
|
2805
|
-
if [ "$budget_admission" -eq 0 ]; then
|
|
2806
|
-
budget_start_renewal
|
|
2807
|
-
elif [ "$cache_served" -eq 1 ]; then
|
|
2808
|
-
# Another agent's identical fetch answered this one while it waited. The
|
|
2809
|
-
# answer is already on stdout and no request was made.
|
|
2810
|
-
exit 0
|
|
2811
|
-
else
|
|
2812
|
-
exit "$budget_admission"
|
|
2813
|
-
fi
|
|
2814
|
-
unset budget_admission
|
|
2815
|
-
fi
|
|
2816
|
-
|
|
2817
|
-
if [ "$track" -eq 1 ] && [ -n "$events_file" ]; then
|
|
2818
|
-
size=0
|
|
2819
|
-
if [ -f "$events_file" ]; then size=$(wc -c < "$events_file" 2>/dev/null || printf '0'); fi
|
|
2820
|
-
case "$size" in
|
|
2821
|
-
''|*[!0-9]*) size=0 ;;
|
|
2822
|
-
esac
|
|
2823
|
-
# Retention (#2255): keep the previous two generations so the agent-side
|
|
2824
|
-
# request record survives the whole detection latency of a budget anomaly
|
|
2825
|
-
# (hours), not just the rolling hour the broker's `admissions` table keeps.
|
|
2826
|
-
if [ "$size" -gt 1048576 ]; then
|
|
2827
|
-
if [ -f "$events_file.1" ]; then mv -f "$events_file.1" "$events_file.2" 2>/dev/null || true; fi
|
|
2828
|
-
mv -f "$events_file" "$events_file.1" 2>/dev/null || true
|
|
2829
|
-
fi
|
|
2830
|
-
|
|
2831
|
-
# The resource column tells the daemon which budget the call was billed to.
|
|
2832
|
-
# Without it every agent call was counted against core, and a GraphQL query —
|
|
2833
|
-
# billed in points against a separate budget — landed in the wrong window.
|
|
2834
|
-
track_resource=$resource
|
|
2835
|
-
case "$track_resource" in
|
|
2836
|
-
core|graphql|search) ;;
|
|
2837
|
-
*) track_resource=core ;;
|
|
2838
|
-
esac
|
|
2839
|
-
|
|
2840
|
-
# Call-site column: allowlisted subcommand, never raw argv (falls back safe).
|
|
2841
|
-
case "$command_name" in
|
|
2842
|
-
''|*[!a-zA-Z0-9-_]*) command_name= ;;
|
|
2843
|
-
esac
|
|
2844
|
-
case "$subcommand_name" in
|
|
2845
|
-
''|*[!a-zA-Z0-9-_]*) subcommand_name= ;;
|
|
2846
|
-
esac
|
|
2847
|
-
call_site=${command_name:-gh}
|
|
2848
|
-
case "$command_name" in
|
|
2849
|
-
api)
|
|
2850
|
-
case "$resource" in
|
|
2851
|
-
graphql) call_site="api graphql" ;;
|
|
2852
|
-
*) call_site=api ;;
|
|
2853
|
-
esac
|
|
2854
|
-
;;
|
|
2855
|
-
pr|issue|run|search|label)
|
|
2856
|
-
case "$subcommand_name" in
|
|
2857
|
-
view|list|status|checks|diff|create|merge|review|close|reopen|edit|ready|delete|comment|update-branch|lock|unlock|pin|unpin|transfer|watch|rerun|cancel|issues|prs|repos|code|commits|users) call_site="$command_name $subcommand_name" ;;
|
|
2858
|
-
esac
|
|
2859
|
-
;;
|
|
2860
|
-
esac
|
|
2861
|
-
|
|
2862
|
-
# The token fingerprint (never the token) answers "which pool did this bill"
|
|
2863
|
-
# without a live /proc sweep, and the wrapper pid lets the daemon correlate
|
|
2864
|
-
# the call with the subprocess-spawn log of the ticket that made it (#2255).
|
|
2865
|
-
# Both are best-effort: an empty fingerprint (budget disabled) or a blank
|
|
2866
|
-
# column degrades to an unattributed row, never a refused call. The call-site
|
|
2867
|
-
# column sits between the resource and the fingerprint (#2299).
|
|
2868
|
-
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$now" "$consumer" "$direction" "$track_resource" "$call_site" "${budget_key:-}" "$$" >> "$events_file" 2>/dev/null || true
|
|
2869
|
-
fi
|
|
2870
|
-
|
|
2871
|
-
error_file=
|
|
2872
|
-
status_file=
|
|
2873
|
-
output_file=
|
|
2874
|
-
api_capture=0
|
|
2875
|
-
api_requested_include=0
|
|
2876
|
-
stderr_streamed=0
|
|
2877
|
-
cache_served_304=0
|
|
2878
|
-
cache_response_etag=
|
|
2879
|
-
cache_conditional_etag=
|
|
2880
|
-
|
|
2881
|
-
# A 304 "Not Modified" is detected from the response status line, never from
|
|
2882
|
-
# gh's exit code: gh exits 1 on a 304, but a served 304 is a SUCCESS that
|
|
2883
|
-
# answers from the cache (#2307 agent conditional reads). Reads the HTTP status
|
|
2884
|
-
# line that `--include` puts at the top of `output_file`.
|
|
2885
|
-
response_status_is_304() {
|
|
2886
|
-
[ -n "$output_file" ] && [ -f "$output_file" ] || return 1
|
|
2887
|
-
awk '/^HTTP\/[^[:space:]]+[[:space:]]+[0-9][0-9][0-9]/ { status = $2 } END { exit status == 304 ? 0 : 1 }' "$output_file"
|
|
2888
|
-
}
|
|
2889
|
-
|
|
2890
|
-
# `gh api` is always run with `--include` so the rate-limit headers can be read,
|
|
2891
|
-
# then the headers are stripped again unless the caller asked for them. The
|
|
2892
|
-
# bytes this prints are what the caller sees, so they are also exactly what the
|
|
2893
|
-
# cache must store. On a served 304 the response carried no body, so the answer
|
|
2894
|
-
# is the cached body — which for an `--include` entry is already the correct
|
|
2895
|
-
# include-shaped bytes (headers and body), and for a plain entry the body alone,
|
|
2896
|
-
# exactly as a fresh cache hit serves the same entry. A 304 means "what you hold
|
|
2897
|
-
# is current" (#2307), so serving the cached body to an `--include` caller must
|
|
2898
|
-
# not be replaced by the bare 304 status line the response actually carried.
|
|
2899
|
-
emit_api_output() {
|
|
2900
|
-
if [ "$cache_served_304" -eq 1 ] && [ -n "$cache_body" ] && [ -f "$cache_body" ]; then
|
|
2901
|
-
cat "$cache_body"
|
|
2902
|
-
elif [ "$api_requested_include" -eq 1 ]; then
|
|
2903
|
-
cat "$output_file"
|
|
2904
|
-
elif sed -n '1p' "$output_file" | grep -Eq '^HTTP/'; then
|
|
2905
|
-
sed '1,/^[[:space:]]*$/d' "$output_file"
|
|
2906
|
-
else
|
|
2907
|
-
cat "$output_file"
|
|
2908
|
-
fi
|
|
2909
|
-
}
|
|
2910
|
-
if [ "$resource" != none ]; then
|
|
2911
|
-
old_umask=$(umask)
|
|
2912
|
-
umask 077
|
|
2913
|
-
error_file=$(mktemp "${TMPDIR:-/tmp}/aiur-gh-stderr.XXXXXX" 2>/dev/null || true)
|
|
2914
|
-
status_file=$(mktemp "${TMPDIR:-/tmp}/aiur-gh-status.XXXXXX" 2>/dev/null || true)
|
|
2915
|
-
umask "$old_umask"
|
|
2916
|
-
fi
|
|
2917
|
-
|
|
2918
|
-
# High-level budgeted commands (anything but `gh api`, which already captures
|
|
2919
|
-
# its status through `--include`) run under `GH_DEBUG=api` so the wrapper can
|
|
2920
|
-
# see whether the response was a free 304. `gh` prints the status line only in
|
|
2921
|
-
# that transcript; without it every `pr view`/`issue view`/`search` 304 is
|
|
2922
|
-
# billed as if it had cost quota (#2353). `run watch` is the one interactive
|
|
2923
|
-
# streamer and is deliberately excluded: its stderr must stay live, and a debug
|
|
2924
|
-
# transcript interleaved with its progress would be worse than the accounting
|
|
2925
|
-
# gap. Every other high-level command is buffered (below) so the transcript is
|
|
2926
|
-
# consumed for reconciliation and then stripped before the caller sees stderr.
|
|
2927
|
-
if [ "$budget_enabled" -eq 1 ] && [ "$resource" != none ] && [ "${1:-}" != api ]; then
|
|
2928
|
-
case "${1:-} ${2:-}" in
|
|
2929
|
-
"run watch") : ;;
|
|
2930
|
-
*) high_level_debug=1 ;;
|
|
2931
|
-
esac
|
|
2932
|
-
fi
|
|
2933
|
-
|
|
2934
|
-
if [ -n "$error_file" ]; then
|
|
2935
|
-
if [ "${1:-}" = api ]; then
|
|
2936
|
-
for api_arg in "$@"; do
|
|
2937
|
-
case "$api_arg" in
|
|
2938
|
-
--include|--include=true|-i) api_requested_include=1 ;;
|
|
2939
|
-
--paginate) : ;;
|
|
2940
|
-
esac
|
|
2941
|
-
done
|
|
2942
|
-
|
|
2943
|
-
if [ "$api_paginated" -eq 0 ]; then
|
|
2944
|
-
old_umask=$(umask)
|
|
2945
|
-
umask 077
|
|
2946
|
-
output_file=$(mktemp "${TMPDIR:-/tmp}/aiur-gh-stdout.XXXXXX" 2>/dev/null || true)
|
|
2947
|
-
umask "$old_umask"
|
|
2948
|
-
[ -n "$output_file" ] && api_capture=1
|
|
2949
|
-
fi
|
|
2950
|
-
fi
|
|
2951
|
-
|
|
2952
|
-
# A cacheable read is captured so its exact bytes can be stored. Only the
|
|
2953
|
-
# shapes classified above reach this branch, and all of them are short,
|
|
2954
|
-
# one-shot, machine-readable reads — nothing that streams progress or prompts,
|
|
2955
|
-
# which is why the `tee` branch below still exists for everything else.
|
|
2956
|
-
if [ -n "$cache_body" ] && [ "$api_capture" -eq 0 ]; then
|
|
2957
|
-
old_umask=$(umask)
|
|
2958
|
-
umask 077
|
|
2959
|
-
cache_stage=$(mktemp "${TMPDIR:-/tmp}/aiur-gh-cache.XXXXXX" 2>/dev/null || true)
|
|
2960
|
-
umask "$old_umask"
|
|
2961
|
-
fi
|
|
2962
|
-
|
|
2963
|
-
if [ "$api_capture" -eq 1 ]; then
|
|
2964
|
-
# stdout is already being captured for header parsing, so there is no live
|
|
2965
|
-
# output to interleave with; buffering stderr here costs nothing.
|
|
2966
|
-
#
|
|
2967
|
-
# Conditional re-read (#2307): when the store holds a body AND a validator
|
|
2968
|
-
# for this resource, the re-fetch sends If-None-Match so an unchanged
|
|
2969
|
-
# answer comes back 304 and is reconciled free instead of billed again. The
|
|
2970
|
-
# validator is only ever offered while a body is held — a 304 with no body
|
|
2971
|
-
# would spend a request and learn nothing (the same contract as the
|
|
2972
|
-
# daemon's ResourceStore). gh exits 1 on a 304, which is not a failure
|
|
2973
|
-
# here: the 304 is detected from the status line below and the cached body
|
|
2974
|
-
# answers the call.
|
|
2975
|
-
cache_conditional_etag=
|
|
2976
|
-
if [ -n "$cache_body" ] && [ -f "$cache_body" ] && [ -f "$cache_meta" ]; then
|
|
2977
|
-
cache_conditional_etag=$(sed -n '2p' "$cache_meta" 2>/dev/null || printf '')
|
|
2978
|
-
fi
|
|
2979
|
-
if [ -n "$cache_conditional_etag" ]; then
|
|
2980
|
-
if [ "$api_requested_include" -eq 1 ]; then
|
|
2981
|
-
run_gh "$@" -H "If-None-Match: $cache_conditional_etag" > "$output_file" 2> "$error_file"
|
|
2982
|
-
else
|
|
2983
|
-
run_gh "$@" -H "If-None-Match: $cache_conditional_etag" --include > "$output_file" 2> "$error_file"
|
|
2984
|
-
fi
|
|
2985
|
-
elif [ "$api_requested_include" -eq 1 ]; then
|
|
2986
|
-
run_gh "$@" > "$output_file" 2> "$error_file"
|
|
2987
|
-
else
|
|
2988
|
-
run_gh "$@" --include > "$output_file" 2> "$error_file"
|
|
2989
|
-
fi
|
|
2990
|
-
status=$?
|
|
2991
|
-
|
|
2992
|
-
# The response's own ETag is what a later re-read validates against. On a
|
|
2993
|
-
# served 304 the response carries the same validator, so capturing it here
|
|
2994
|
-
# also keeps the entry's validator in place. `tr` is gated because an
|
|
2995
|
-
# isolated `PATH` (the test harness, a hardened shell) may lack it; without
|
|
2996
|
-
# it a trailing CR is left on the stored validator, which only costs a
|
|
2997
|
-
# later 304 match, never correctness.
|
|
2998
|
-
if [ -n "$output_file" ] && [ -f "$output_file" ]; then
|
|
2999
|
-
cache_response_etag=$(sed -n -E 's/^[[:space:]]*[Ee][Tt][Aa][Gg]:[[:space:]]*(.*)$/\1/p' "$output_file" | tail -n 1)
|
|
3000
|
-
if command -v tr >/dev/null 2>&1; then
|
|
3001
|
-
cache_response_etag=$(printf '%s\n' "$cache_response_etag" | tr -d '\r')
|
|
3002
|
-
fi
|
|
3003
|
-
fi
|
|
3004
|
-
|
|
3005
|
-
if response_status_is_304 && [ -n "$cache_body" ] && [ -f "$cache_body" ]; then
|
|
3006
|
-
cache_served_304=1
|
|
3007
|
-
status=0
|
|
3008
|
-
fi
|
|
3009
|
-
elif [ -n "$cache_stage" ]; then
|
|
3010
|
-
if [ "$high_level_debug" -eq 1 ]; then
|
|
3011
|
-
( GH_DEBUG=api; export GH_DEBUG; run_gh "$@" ) > "$cache_stage" 2> "$error_file"
|
|
3012
|
-
else
|
|
3013
|
-
run_gh "$@" > "$cache_stage" 2> "$error_file"
|
|
3014
|
-
fi
|
|
3015
|
-
status=$?
|
|
3016
|
-
cat "$cache_stage"
|
|
3017
|
-
elif [ -n "$status_file" ] && command -v tee > /dev/null 2>&1 && [ "$high_level_debug" -eq 0 ]; then
|
|
3018
|
-
# Pass stderr through `tee` so it reaches the terminal as it is written
|
|
3019
|
-
# while still being captured for the rate-limit classification below.
|
|
3020
|
-
# Replaying a buffered copy after exit stalls `gh run watch` progress — an
|
|
3021
|
-
# allowlisted read — and swallows interactive prompts. `tee` ends the
|
|
3022
|
-
# pipeline, so the real exit status travels via `status_file`.
|
|
3023
|
-
{ { run_gh "$@"; printf '%s\n' "$?" > "$status_file"; } 2>&1 1>&3 | tee "$error_file" >&2; } 3>&1
|
|
3024
|
-
stderr_streamed=1
|
|
3025
|
-
# An unreadable or non-numeric status means the real exit code could not be
|
|
3026
|
-
# confirmed. Reporting 0 there would turn a failed `gh` into an apparent
|
|
3027
|
-
# success for every caller, so this fails closed instead.
|
|
3028
|
-
status=$(sed -n '1p' "$status_file" 2>/dev/null)
|
|
3029
|
-
case "$status" in
|
|
3030
|
-
''|*[!0-9]*) status=1 ;;
|
|
3031
|
-
esac
|
|
3032
|
-
else
|
|
3033
|
-
if [ "$high_level_debug" -eq 1 ]; then
|
|
3034
|
-
( GH_DEBUG=api; export GH_DEBUG; run_gh "$@" ) 2> "$error_file"
|
|
3035
|
-
else
|
|
3036
|
-
run_gh "$@" 2> "$error_file"
|
|
3037
|
-
fi
|
|
3038
|
-
status=$?
|
|
3039
|
-
fi
|
|
3040
|
-
|
|
3041
|
-
if [ "$api_capture" -eq 1 ]; then
|
|
3042
|
-
emit_api_output
|
|
3043
|
-
|
|
3044
|
-
# The cache copy is produced by a SECOND pass rather than by redirecting the
|
|
3045
|
-
# first. The agent's stdout must not depend on the cache being writable.
|
|
3046
|
-
# On a served 304 the response carried no body, so nothing is re-stored —
|
|
3047
|
-
# the existing body stays and the entry's stamp is refreshed below.
|
|
3048
|
-
if [ "$cache_served_304" -eq 0 ] && [ -n "$cache_body" ] && [ "$status" -eq 0 ]; then
|
|
3049
|
-
old_umask=$(umask)
|
|
3050
|
-
umask 077
|
|
3051
|
-
cache_stage=$(mktemp "${TMPDIR:-/tmp}/aiur-gh-cache.XXXXXX" 2>/dev/null || true)
|
|
3052
|
-
umask "$old_umask"
|
|
3053
|
-
if [ -n "$cache_stage" ]; then emit_api_output > "$cache_stage" 2>/dev/null || cache_stage=; fi
|
|
3054
|
-
fi
|
|
3055
|
-
fi
|
|
3056
|
-
|
|
3057
|
-
# High-level 304s reconcile here, before the transcript would otherwise leak:
|
|
3058
|
-
# the status is read for reconciliation and then the debug is stripped so the
|
|
3059
|
-
# replay below is exactly the stderr the caller would have seen without it.
|
|
3060
|
-
if [ "$high_level_debug" -eq 1 ]; then
|
|
3061
|
-
budget_reconcile_debug
|
|
3062
|
-
fi
|
|
3063
|
-
|
|
3064
|
-
if [ "$stderr_streamed" -eq 0 ]; then
|
|
3065
|
-
while IFS= read -r line || [ -n "$line" ]; do
|
|
3066
|
-
# gh prints `gh: HTTP 304` on stderr for a served 304 — noise that would
|
|
3067
|
-
# read as a failure. A 304 is a success answered from the cache.
|
|
3068
|
-
if [ "$cache_served_304" -eq 1 ] && printf '%s\n' "$line" | grep -Eiq '^gh: HTTP 304'; then
|
|
3069
|
-
continue
|
|
3070
|
-
fi
|
|
3071
|
-
printf '%s\n' "$line" >&2
|
|
3072
|
-
done < "$error_file"
|
|
3073
|
-
fi
|
|
3074
|
-
else
|
|
3075
|
-
run_gh "$@"
|
|
3076
|
-
status=$?
|
|
3077
|
-
fi
|
|
3078
|
-
|
|
3079
|
-
probe_rate_limit() {
|
|
3080
|
-
original_resource=$resource
|
|
3081
|
-
original_admission_resource=$admission_resource
|
|
3082
|
-
original_family=$endpoint_family
|
|
3083
|
-
# The probe is a different request against a different resource. Claiming the
|
|
3084
|
-
# original read's shape for it would make every follower wait on an answer this
|
|
3085
|
-
# call is never going to write — and, worse, admission is re-entered here AFTER
|
|
3086
|
-
# the real `gh` has already failed, so a cached body found during the probe
|
|
3087
|
-
# would be printed onto the stdout of a call about to exit non-zero
|
|
3088
|
-
# (`$(gh ... --json ...)` would read that as success). Both the claim and the
|
|
3089
|
-
# ability to serve are withdrawn for the duration.
|
|
3090
|
-
original_claim_key=$cache_claim_key
|
|
3091
|
-
original_cache_body=$cache_body
|
|
3092
|
-
cache_claim_key=
|
|
3093
|
-
cache_body=
|
|
3094
|
-
immediate_cooldown=$(secondary_delay_ms "$error_file" "$output_file")
|
|
3095
|
-
budget_hold token "$immediate_cooldown"
|
|
3096
|
-
budget_release
|
|
3097
|
-
resource=core
|
|
3098
|
-
admission_resource=core
|
|
3099
|
-
endpoint_family=rate_limit
|
|
3100
|
-
budget_ignore_token_cooldown=1
|
|
3101
|
-
if budget_acquire; then
|
|
3102
|
-
budget_start_renewal
|
|
3103
|
-
rate_limit_observation=$(run_gh api rate_limit --template '{{.resources.core.remaining}} {{.resources.core.reset}} {{.resources.graphql.remaining}} {{.resources.graphql.reset}}' 2>/dev/null || true)
|
|
3104
|
-
else
|
|
3105
|
-
rate_limit_observation=
|
|
3106
|
-
fi
|
|
3107
|
-
budget_ignore_token_cooldown=0
|
|
3108
|
-
budget_release
|
|
3109
|
-
resource=$original_resource
|
|
3110
|
-
admission_resource=$original_admission_resource
|
|
3111
|
-
endpoint_family=$original_family
|
|
3112
|
-
cache_claim_key=$original_claim_key
|
|
3113
|
-
cache_body=$original_cache_body
|
|
3114
|
-
unset original_resource original_admission_resource original_family original_claim_key original_cache_body \
|
|
3115
|
-
immediate_cooldown
|
|
3116
|
-
}
|
|
3117
|
-
|
|
3118
|
-
rate_limited_response() {
|
|
3119
|
-
grep -Eiq 'rate.?limit|rate_limit' "$error_file" && return 0
|
|
3120
|
-
[ -n "$output_file" ] && grep -Eiq 'rate.?limit|rate_limit' "$output_file" && return 0
|
|
3121
|
-
[ -n "$output_file" ] && grep -Eq '^HTTP/[0-9.]+[[:space:]]+(403|429)' "$output_file" && grep -Eiq '^[Rr]etry-[Aa]fter:' "$output_file"
|
|
3122
|
-
}
|
|
3123
|
-
|
|
3124
|
-
record_successful_budget_hold() {
|
|
3125
|
-
[ "$status" -eq 0 ] || return 0
|
|
3126
|
-
[ -n "$output_file" ] && [ -f "$output_file" ] || return 0
|
|
3127
|
-
|
|
3128
|
-
response_remaining=$(sed -n -E 's/^[[:space:]]*[Xx]-[Rr][Aa][Tt][Ee][Ll][Ii][Mm][Ii][Tt]-[Rr][Ee][Mm][Aa][Ii][Nn][Ii][Nn][Gg]:[[:space:]]*([0-9]+).*/\1/p' "$output_file" | tail -n 1)
|
|
3129
|
-
response_reset=$(sed -n -E 's/^[[:space:]]*[Xx]-[Rr][Aa][Tt][Ee][Ll][Ii][Mm][Ii][Tt]-[Rr][Ee][Ss][Ee][Tt]:[[:space:]]*([0-9]+).*/\1/p' "$output_file" | tail -n 1)
|
|
3130
|
-
|
|
3131
|
-
case "$response_remaining:$response_reset" in
|
|
3132
|
-
0:[0-9]*)
|
|
3133
|
-
response_delay=$(( (response_reset - $(date -u +%s)) * 1000 ))
|
|
3134
|
-
if [ "$response_delay" -gt 0 ]; then
|
|
3135
|
-
publish_hold "$resource-hold" "$response_reset"
|
|
3136
|
-
budget_hold resource "$response_delay" "$resource"
|
|
3137
|
-
fi
|
|
3138
|
-
;;
|
|
3139
|
-
esac
|
|
3140
|
-
|
|
3141
|
-
unset response_remaining response_reset response_delay
|
|
3142
|
-
}
|
|
3143
|
-
|
|
3144
|
-
record_successful_budget_hold
|
|
3145
|
-
budget_reconcile_response
|
|
3146
|
-
|
|
3147
|
-
# A mutation invalidates before its response is stored, so an agent that edits a
|
|
3148
|
-
# pull request and immediately reads it back can never be answered from the copy
|
|
3149
|
-
# it just superseded. Invalidation runs whatever the exit status was: a write
|
|
3150
|
-
# that failed late may still have landed.
|
|
3151
|
-
if [ -n "$cache_root" ]; then
|
|
3152
|
-
cache_old_umask=$(umask)
|
|
3153
|
-
umask 077
|
|
3154
|
-
fi
|
|
3155
|
-
cache_invalidate_writes
|
|
3156
|
-
cache_store
|
|
3157
|
-
# A served 304 confirmed the cached body is current: refresh the fetched-at
|
|
3158
|
-
# stamp so the entry stays warm (the re-validated answer is as fresh as a 200)
|
|
3159
|
-
# while keeping the stored body — the 304 carried no bytes to store.
|
|
3160
|
-
if [ "$cache_served_304" -eq 1 ] && [ -n "$cache_meta" ]; then
|
|
3161
|
-
cache_meta_body=$cache_started_at
|
|
3162
|
-
if [ -n "$cache_conditional_etag" ]; then cache_meta_body="$cache_started_at
|
|
3163
|
-
$cache_conditional_etag"; fi
|
|
3164
|
-
cache_write_file "$cache_meta" "$cache_meta_body" || true
|
|
3165
|
-
unset cache_meta_body
|
|
3166
|
-
fi
|
|
3167
|
-
cache_prune
|
|
3168
|
-
if [ -n "$cache_root" ]; then umask "$cache_old_umask"; fi
|
|
3169
|
-
if [ -n "$cache_stage" ]; then rm -f "$cache_stage" 2>/dev/null || true; fi
|
|
3170
|
-
|
|
3171
|
-
if [ "$status" -ne 0 ] && [ -n "$error_file" ] && rate_limited_response && { [ -n "$agent_quota_dir" ] || [ "$budget_enabled" -eq 1 ]; }; then
|
|
3172
|
-
probe_rate_limit
|
|
3173
|
-
observation=$rate_limit_observation
|
|
3174
|
-
unset rate_limit_observation
|
|
3175
|
-
set -- $observation
|
|
3176
|
-
exhausted=0
|
|
3177
|
-
|
|
3178
|
-
if [ "$#" -eq 4 ]; then
|
|
3179
|
-
core_remaining=$1
|
|
3180
|
-
core_reset=$2
|
|
3181
|
-
graphql_remaining=$3
|
|
3182
|
-
graphql_reset=$4
|
|
3183
|
-
|
|
3184
|
-
case "$core_remaining:$core_reset" in
|
|
3185
|
-
0:[0-9]*)
|
|
3186
|
-
publish_hold "core-hold" "$core_reset"
|
|
3187
|
-
budget_delay=$(( (core_reset - $(date -u +%s)) * 1000 ))
|
|
3188
|
-
if [ "$budget_delay" -gt 0 ]; then budget_hold resource "$budget_delay" core; fi
|
|
3189
|
-
exhausted=1
|
|
3190
|
-
;;
|
|
3191
|
-
esac
|
|
3192
|
-
case "$graphql_remaining:$graphql_reset" in
|
|
3193
|
-
0:[0-9]*)
|
|
3194
|
-
publish_hold "graphql-hold" "$graphql_reset"
|
|
3195
|
-
budget_delay=$(( (graphql_reset - $(date -u +%s)) * 1000 ))
|
|
3196
|
-
if [ "$budget_delay" -gt 0 ]; then budget_hold resource "$budget_delay" graphql; fi
|
|
3197
|
-
exhausted=1
|
|
3198
|
-
;;
|
|
3199
|
-
esac
|
|
3200
|
-
|
|
3201
|
-
if [ "$exhausted" -eq 1 ]; then
|
|
3202
|
-
printf '%s\n' 'aiur: GitHub quota exhausted; exact reset backoff recorded' >&2
|
|
3203
|
-
fi
|
|
3204
|
-
fi
|
|
3205
|
-
|
|
3206
|
-
# A rate-limit refusal while both primary windows still read healthy is a
|
|
3207
|
-
# secondary (abuse) limit. Nothing in the primary windows records it, so
|
|
3208
|
-
# without its own backoff the next call retries straight into another
|
|
3209
|
-
# rejection. Honour Retry-After when gh exposes it, with GitHub's 60-second
|
|
3210
|
-
# guidance as the fallback.
|
|
3211
|
-
if [ "$exhausted" -eq 0 ]; then
|
|
3212
|
-
secondary_delay=$(secondary_delay_ms "$error_file" "$output_file")
|
|
3213
|
-
secondary_wait_seconds=$(( (secondary_delay + 999) / 1000 ))
|
|
3214
|
-
secondary_until=$(( $(date -u +%s) + secondary_wait_seconds ))
|
|
3215
|
-
|
|
3216
|
-
case "$resource" in
|
|
3217
|
-
core|graphql) publish_hold "$resource-secondary-hold" "$secondary_until" ;;
|
|
3218
|
-
*)
|
|
3219
|
-
publish_hold "core-secondary-hold" "$secondary_until"
|
|
3220
|
-
publish_hold "graphql-secondary-hold" "$secondary_until"
|
|
3221
|
-
;;
|
|
3222
|
-
esac
|
|
3223
|
-
|
|
3224
|
-
printf 'aiur: GitHub secondary rate limit; backing off %ss before the next call\n' "$secondary_wait_seconds" >&2
|
|
3225
|
-
budget_hold token "$secondary_delay"
|
|
3226
|
-
fi
|
|
3227
|
-
fi
|
|
3228
|
-
|
|
3229
|
-
budget_release
|
|
3230
|
-
if [ -n "$error_file" ]; then rm -f "$error_file" 2>/dev/null || true; fi
|
|
3231
|
-
if [ -n "$status_file" ]; then rm -f "$status_file" 2>/dev/null || true; fi
|
|
3232
|
-
if [ -n "$output_file" ]; then rm -f "$output_file" 2>/dev/null || true; fi
|
|
3233
|
-
exit "$status"
|