Initial commit on Forgejo
All checks were successful
CI and deploy / Test (push) Successful in 4m52s
CI and deploy / Deploy production (push) Successful in 23s

Fresh repository history for elektrine/tarakan hosted at
https://git.elektrine.com/elektrine/tarakan.
This commit is contained in:
Maxfield Luke 2026-07-29 04:43:40 -04:00
commit af6077b9c3
455 changed files with 78366 additions and 0 deletions

209
config/config.exs Normal file
View file

@ -0,0 +1,209 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
# General application configuration
import Config
config :tarakan, secure_cookies: true
# Contact published in /.well-known/security.txt; overridden in prod runtime.
config :tarakan, security_contact: "security@example.com"
config :tarakan, :scopes,
account: [
default: true,
module: Tarakan.Accounts.Scope,
assign_key: :current_scope,
access_path: [:account, :id],
schema_key: :account_id,
schema_type: :id,
schema_table: :accounts,
test_data_fixture: Tarakan.AccountsFixtures,
test_setup_helper: :register_and_log_in_account
]
config :tarakan,
ecto_repos: [Tarakan.Repo],
generators: [timestamp_type: :utc_datetime],
github_client: Tarakan.GitHub.HTTPClient,
github_bulk_client: Tarakan.GitHub.GraphQLClient,
github_oauth_client: Tarakan.GitHub.OAuth.HTTPClient,
gitlab_oauth_client: Tarakan.GitLab.OAuth.HTTPClient,
# Finding-kind Request complete requires a Review Format document (Findings path).
# Legacy prose remains for write_fix / verify_findings and for tests that opt into dual mode.
request_completion_mode: :document_required,
stripe_api: Tarakan.Billing.Stripe.API,
stripe_secret_key: nil,
stripe_webhook_secret: nil,
# Placeholder plan prices; real ids come from runtime env in prod.
stripe_price_enterprise: "price_enterprise_placeholder",
# Platform share of bounties, snapshotted onto each bounty at creation.
market_take_rate: 0.10
config :tarakan, :github,
api_version: "2026-03-10",
client_id: nil,
client_secret: nil,
api_token: nil
config :tarakan, Tarakan.RepositoryCode,
global_upstream_limit: 240,
repository_upstream_limit: 60,
upstream_window_seconds: 60,
identity_cache_ttl_ms: 3_000,
identity_revalidation_ttl_ms: 86_400_000,
head_cache_ttl_ms: 12_000,
immutable_cache_ttl_ms: 86_400_000
# Public aggregate queries (posture, badges, model analytics, the suppression
# corpus). Short enough that the record still reads as live; long enough that
# an unauthenticated endpoint cannot replay the query on demand.
config :tarakan, Tarakan.AnalyticsCache, ttl_ms: 60_000
config :tarakan, Tarakan.RepositoryMirror,
enabled: true,
# Production code browse uses git mirrors only (no GitHub REST for objects).
rest_fallback: false,
root: "priv/mirrors"
config :tarakan, Tarakan.HostedRepositories,
root: "priv/hosted",
max_push_bytes: 262_144_000,
quota_bytes: 1_073_741_824
config :tarakan, Tarakan.GitSSH,
enabled: false,
port: 2222,
host_key_dir: "priv/ssh"
# Cap concurrent git upload-pack/receive-pack processes (HTTP RPC + SSH).
config :tarakan, Tarakan.Git.Concurrency, max_concurrent: 32
config :tarakan, Oban,
engine: Oban.Engines.Basic,
repo: Tarakan.Repo,
# infestations: 1 keeps DB pool pressure low (compose POOL_SIZE default is 5).
queues: [sync: 5, mirror: 3, infestations: 1, credits: 1, market: 1, billing: 1],
plugins: [
{Oban.Plugins.Pruner, max_age: 7 * 24 * 60 * 60},
{Oban.Plugins.Cron,
crontab: [
{"0 3 * * *", Tarakan.Sync.RepositorySweep},
{"30 3 * * *", Tarakan.Infestations.Reconcile},
# No-op until :swarm_sweep names an actor; runs after the reconcile so
# it sees the rollups that pass refreshed.
{"45 3 * * *", Tarakan.Infestations.SwarmSweep},
{"0 4 * * 0", Tarakan.Sync.HostedRepositoryGC},
{"0 * * * *", Tarakan.Infestations.RecomputeWindows},
{"15 * * * *", Tarakan.Market.SweepWorker},
{"0 9 * * *", Tarakan.Billing.AlertWorker}
]}
]
# The nightly swarm sweep fans check jobs onto other contributors' agents, so
# it stays inert until an operator names the account it opens them as.
config :tarakan, :swarm_sweep,
actor_handle: nil,
patterns_per_run: 25,
jobs_per_run: 40,
max_jobs_per_pattern: 8,
min_repos: 3,
days: 90
# Infestation rollups: async projection + dual-read. Tests set sync_refresh: true.
config :tarakan, :infestations,
read_from_rollup: true,
refresh_async: true,
sync_refresh: false
config :tarakan, :gitlab,
base_url: "https://gitlab.com",
client_id: nil,
client_secret: nil
# Configure the endpoint
config :tarakan, TarakanWeb.Endpoint,
url: [host: "localhost"],
adapter: Bandit.PhoenixAdapter,
render_errors: [
formats: [html: TarakanWeb.ErrorHTML, json: TarakanWeb.ErrorJSON],
layout: false
],
pubsub_server: Tarakan.PubSub,
live_view: [signing_salt: "Ht50NGTc"]
# Configure LiveView
config :phoenix_live_view,
# the attribute set on all root tags. Used for Phoenix.LiveView.ColocatedCSS.
root_tag_attribute: "phx-r"
# Configure the mailer
#
# By default it uses the "Local" adapter which stores the emails
# locally. You can see the emails in your browser, at "/dev/mailbox".
#
# For production it's recommended to configure a different adapter
# at the `config/runtime.exs`.
config :tarakan, Tarakan.Mailer, adapter: Swoosh.Adapters.Local
# Configure esbuild (the version is required)
config :esbuild,
version: "0.25.4",
tarakan: [
args:
~w(js/app.js --bundle --target=es2022 --format=esm --splitting --outdir=../priv/static/assets/js --external:/fonts/* --external:/images/* --alias:@=.),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
],
# Separate profile because this one must ship as a classic script: it runs
# blocking in <head> before first paint, and a module is always deferred.
theme: [
args:
~w(js/theme.js --bundle --target=es2017 --format=iife --outdir=../priv/static/assets/js),
cd: Path.expand("../assets", __DIR__),
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
]
# Configure tailwind (the version is required)
config :tailwind,
version: "4.3.0",
tarakan: [
args: ~w(
--input=assets/css/app.css
--output=priv/static/assets/css/app.css
),
cd: Path.expand("..", __DIR__),
env: %{"NODE_PATH" => [Path.expand("../deps", __DIR__), Mix.Project.build_path()]}
]
# Configure Elixir's Logger
config :logger, :default_formatter,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Use Jason for JSON parsing in Phoenix
config :phoenix,
json_library: Jason,
filter_parameters: [
"authorization",
"code",
"credential",
"description",
"document",
"evidence",
"findings",
"findings_json",
"notes",
"password",
"reason",
"secret",
"summary",
"token"
]
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{config_env()}.exs"