Skip to content

Borge-Labs/ai-team

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AI Team

License: MIT

Status: working research project from Borge Labs, published as-is. It runs our own Slack workspace every day, but it is not a supported product: issues and PRs are welcome but may go unanswered.

AI Team is an open-source, Slack-native AI staff framework for small, high-context teams. It gives a Slack workspace configurable AI teammates who can follow discussions, remember decisions, understand docs and repositories, inspect public web pages and, in the opt-in browser build, screenshots, and help move work forward without adding another app.

Instead of one generic chatbot, AI Team behaves like a coordinated team. Each teammate has a name, role, model, tools and scope. A team lead routes questions to the right specialists, or coordinates a combined answer when a topic needs product, technical, design, growth, research, legal-style compliance or operational input.

Teammates discuss, draft, review and recommend. Irreversible actions should stay human-approved and tool-gated.

Why It Is Different

  • Slack-first: the team works where company discussions already happen.
  • Team-shaped: configure named teammates with roles, models, prompts and tools.
  • Context-aware: combine thread history, channel memory, live docs, repo context, web reads, screenshots and uploaded images.
  • Workstream-scoped: each channel can have its own context boundary, repository scope and operating rules.
  • Model-agnostic: route different teammates to different providers based on quality, cost and latency.
  • Open-source and config-first: keep the framework generic, then mount your own config, secrets and deployment choices.

What It Can Do

AI Team can help teams:

  • discuss strategy, product, technical, design, growth, legal-style and operational questions with role-matched teammates
  • answer from real context: configured GitHub repositories, team docs, thread history and per-channel memory
  • read public web pages, search the web, and capture pages or screenshots for UI/UX review; analyze uploaded images and mockups
  • draft and consolidate prompts for coding agents
  • run daily kickoff threads, scheduled checks and public-URL watchers, all confirmed from Slack
  • preserve durable decisions per workstream while keeping channel context separate
  • update exactly allowlisted Markdown docs through a GitHub App on an explicit request from a configured Slack admin
  • log estimated model usage and stop new runtime calls at a configurable soft daily threshold

Automations are notify-only by default. They can monitor, summarize, draft and recommend in Slack; irreversible external actions still need explicit human approval and a safe tool path.

Example Workflows

Ask:

What changed in the repo since yesterday?

The technical teammate can check configured GitHub repositories, compare current state with indexed context, and explain the impact in Slack.

Ask:

Review this landing page against our positioning.

Product, growth and design teammates can inspect a public URL or screenshot, compare it with saved direction, and return a practical recommendation.

Ask:

Summarize what we decided in this thread and remember it.

The team can turn a Slack discussion into durable memory or an updated Markdown doc, scoped to the right workstream.

Ask:

Can the legal/compliance teammate review this privacy copy?

A configured compliance-oriented teammate can issue-spot, draft safer wording and flag legal risk. It is support for human review, not legal advice.

Memory And Context

AI Team combines several context layers:

  • recent channel context for short-term awareness
  • full thread context for ongoing discussions
  • live team docs stored in Postgres
  • saved decision-grade memories
  • indexed repository chunks from GitHub
  • live GitHub, web, URL, screenshot and image context when relevant

Memory is scoped by channel and workstream to reduce context bleed between projects. Slack deletion events can remove matching source messages and derived memory/artifacts.

context-pack.md is only bootstrap context. After startup, live memory and team docs live in Postgres.

Trust And Control

Admins configure:

  • allowed Slack channels
  • teammates, roles, models, tools and routing hints
  • repository scopes per channel
  • memory document keys and bootstrap context
  • exact, admin-only GitHub Markdown update targets
  • provider credentials through environment variables or secret managers
  • best-effort estimated runtime-model thresholds and usage logging

The framework blocks unsafe public URL targets such as localhost, private network addresses and metadata hosts. Secrets should never live in config files.

Before connecting a real workspace, read Privacy and Threat Model. This service stores Slack content and can send selected working context to model providers; it has no automatic retention period.

Quick Start

You need Docker with Compose, a Slack workspace where you can install an app, an OpenAI API key, and a public HTTPS URL that Slack can reach. The first run builds the image locally; it does not depend on GHCR being public.

In Slack, first create a blank app from scratch for your workspace. Copy its signing secret from Basic Information, but do not enable Socket Mode.

Create the documented three-person, one-provider starter config and environment file:

cp -R starter-config my-config
cp .env.example .env

Set OPENAI_API_KEY and the blank app's SLACK_SIGNING_SECRET in .env, then replace the placeholder company context in my-config/context-pack.md. Leave the bot token empty for this bootstrap start and run:

docker compose up --build -d
docker compose ps
curl --fail http://localhost:8080/healthz

Compose starts Postgres with pgvector, waits for it to become healthy, applies all numbered migrations exactly once, starts AI Team, and persists database and artifact data in named volumes.

A one-shot artifact-init service gives UID/GID 10001 ownership of the artifact volume before AI Team starts. The initializer exits after that narrow operation; the application itself continues to run as the non-root UID/GID 10001.

Port 8080 binds to 127.0.0.1 by default. Configure your public HTTPS ingress or development tunnel to proxy to that loopback address; do not publish the plain HTTP app port directly on an external interface.

Now replace both https://ai-team.example.com URLs in slack-app-manifest.yaml with your public HTTPS origin. Open App Manifest for the existing blank Slack app and apply that YAML. Slack can now verify the signed callback against the running service. Install the app, then copy its bot token and an allowed channel ID into .env. Restart with docker compose up -d and invite the bot. See Slack App for the exact callback flow.

External database

Setting DATABASE_URL alone does not disable the bundled database service. For operator-managed Postgres+pgvector, set the full URL and use the override (Docker Compose 2.24.4 or newer):

docker compose -f docker-compose.yml -f docker-compose.external-db.yml up --build -d

The override removes Postgres from AI Team's dependencies and leaves the bundled service behind a disabled profile. Set AI_TEAM_RUN_MIGRATIONS=false only when your deployment process has already applied every numbered migration. That flag skips both entrypoint migrations and runtime compatibility DDL; the app still expects the complete schema and performs normal reads/writes.

The bundled URL interpolates POSTGRES_PASSWORD directly. Keep that local password URL-safe (letters, digits, ., _, ~, or -). For a password with reserved URL characters, keep the raw value in POSTGRES_PASSWORD and set an explicit DATABASE_URL whose password component is percent-encoded.

The richer example-config/ demonstrates more roles, workstreams and optional integrations after the starter is working.

Published image (release step)

The repository is intentionally buildable before its container package is public. A research release should publish a versioned image tag such as:

ghcr.io/borge-labs/ai-team:0.1.0-research

The version tag is a human-readable release pointer; only the resolved image digest is immutable. Operators can then use the published image from their container platform. The published/default runtime target uses a pinned Alpine base and deliberately omits Playwright and Chromium. Do not rely on latest for a known-good deployment. Making the GHCR package public is a separate release action; this repository does not change package or repository visibility.

Opt-in browser capture

Browser capture is disabled by default and is not present in the published Alpine runtime image. The opt-in browser target uses pinned Debian/Trixie for Playwright's glibc-based Chromium. To test it locally, set both of these values in .env and rebuild:

AI_TEAM_BUILD_TARGET=browser
AI_TEAM_WEB_CAPTURE_ENABLED=true
docker compose up --build -d

For a Python installation, install the optional dependency with python -m pip install -e '.[browser]', then run python -m playwright install --with-deps chromium as an operator-controlled setup step. Chromium runs with --no-sandbox; use the browser target only in a separate disposable environment with no secrets or private-network access. The normal application container is not a security boundary for hostile pages.

Compose mounts your config read-only:

./my-config -> /app/config

Configuration

CONFIG_PATH must point to a directory containing:

  • team.yaml: team name, language, roster, aliases, model choices, routing policy, tool hints and bootstrap document keys.
  • context-pack.md: one-time seed context for live team docs.
  • personas/*.md: long-form persona instructions.

Use starter-config/ for the first deployment and example-config/ to explore the fuller contract. See CONFIG.md for details.

Environment Variables

Name Required Description
SLACK_BOT_TOKEN Yes Slack bot token used to post messages.
SLACK_SIGNING_SECRET Yes Verifies every Slack HTTPS event and interaction request.
OPENAI_API_KEY For the starter The starter config's only model-provider credential.
AI_TEAM_UTILITY_MODEL Optional Model for background summaries, open-loop tracking, memory updates, GitHub Markdown drafting and opt-in casting feedback. Defaults to AI_TEAM_CHAIR_ROUTER_MODEL; the starter pins both to OpenAI.
AI_TEAM_FALLBACK_MODELS Optional Ordered comma-separated fallback models for failed/refused chat calls. Empty by default. Each entry is an explicit choice to resend the same Slack/context payload to that model/provider.
CONFIG_PATH No Config directory inside the container. Compose sets /app/config.
SLACK_BOARDROOM_CHANNEL_ID For the starter Primary Slack channel and the starter's default allow-list.
SLACK_ALLOWED_CHANNEL_IDS Optional Additional comma-separated channels the app may answer in. If no channel IDs are configured anywhere, Slack events fail closed.
SLACK_PROJECT_CONTEXT_CHANNEL_ID Optional Channel that owns shared live team docs. Defaults to the primary channel.
AI_TEAM_ADMIN_SLACK_USER_IDS For action approvals Comma-separated Slack user IDs allowed to approve/deny/abort coding jobs, apply allowlisted GitHub Markdown writes, and administer another user's automation.
DATABASE_URL In production Postgres+pgvector connection string. Compose supplies a local default when empty.
AI_TEAM_RUN_MIGRATIONS Optional Apply numbered migrations and allow runtime compatibility DDL. Defaults to true; set false only for a complete externally managed schema.
AI_TEAM_INTERNAL_TOKEN Optional Bearer token for protected maintenance endpoints.
ANTHROPIC_API_KEY Optional Enables anthropic/... models.
DEEPSEEK_API_KEY Optional Enables deepseek/... models.
MIMO_API_KEY Optional Enables mimo/... models.
OPENROUTER_API_KEY Optional Enables openrouter/... models through the OpenRouter gateway, for example openrouter/z-ai/glm-5.2.
GOOGLE_CLOUD_PROJECT / VERTEX_PROJECT For Vertex/Gemini features Enables Vertex models, embeddings, web search and image generation.
AI_TEAM_GCS_BUCKET For persisted visual artifacts Stores screenshots and generated images.
AI_TEAM_ARTIFACT_DIR Optional Local/PVC artifact directory for screenshots and generated images when GCS is not used.
AI_TEAM_ARTIFACT_BASE_URL Optional Public or internal URL prefix for locally stored artifacts.
AI_TEAM_LOCAL_AI_BASE_URL Optional OpenAI-compatible /v1 base URL for local chat or vision models, for example llama.cpp/vLLM.
AI_TEAM_LOCAL_AI_API_KEY Optional Bearer token for the local OpenAI-compatible model endpoint, if required.
AI_TEAM_PERSONAL_DATA_EGRESS Optional Text-payload policy for real Norwegian personal identifiers (fødselsnummer/D-nummer) sent to OpenAI/Anthropic/DeepSeek/MiMo/OpenRouter: redact (default), block, or off. It cannot inspect image bytes or custom embedding/web-gateway calls. Vertex and local/ models bypass it; verify their actual region/endpoints separately.
AI_TEAM_VISION_MODEL Optional Primary model used for screenshot and uploaded-image analysis. Supports Vertex, OpenAI-compatible MiMo/OpenRouter, and local/<served-model> with AI_TEAM_LOCAL_AI_BASE_URL. Defaults to VERTEX_VISION_MODEL (google/gemini-3.1-pro-preview). Long pages are captured as viewport-height tiles so text stays legible.
AI_TEAM_VISION_FALLBACK_MODEL Optional Secondary vision model tried when the primary vision model fails. Defaults to google/gemini-3.5-flash.
AI_TEAM_EMBEDDING_BASE_URL Optional OpenAI-compatible /v1 base URL for repo-context embeddings.
AI_TEAM_EMBEDDING_API_KEY Optional Bearer token for the OpenAI-compatible embedding backend.
AI_TEAM_EMBEDDING_MODEL Optional Embedding model name for repository/context semantic search. Empty disables embedding calls; setting it explicitly uses the configured embedding backend or Vertex project.
AI_TEAM_EMBEDDING_VECTOR_DIMENSIONS Optional Truncate embedding vectors to match the database schema, for example 768.
AI_TEAM_WEB_RESEARCH_GATEWAY_URL Optional Screened web gateway URL for public web/source context instead of Vertex Google Search grounding.
AI_TEAM_IMAGE_GENERATION_ENABLED Optional Enables the image generation button/action. Defaults to false.
AI_TEAM_IMAGE_MODEL Optional Image generation model when image generation is enabled. Defaults to VERTEX_IMAGE_MODEL.
AI_TEAM_IMAGE_ESTIMATED_COST_USD Optional Fixed estimated cost recorded after each successful image-generation provider call. Defaults to 0.05; image APIs do not report token usage here.
GITHUB_APP_ID Optional GitHub App id for repo indexing and Markdown updates.
GITHUB_APP_PRIVATE_KEY_PEM Optional GitHub App private key, supplied only through environment/secrets.
GITHUB_APP_INSTALLATION_ID Optional GitHub App installation id.
GITHUB_ADDITIONAL_APPS Optional Additional owner=app_id:installation_id:PRIVATE_KEY_ENV app mappings.
GITHUB_REPOS Optional Comma-separated owner/repo or owner/* repo specs to index.
GITHUB_REPO_CHANNEL_SCOPES Optional Per-channel repo read/index scopes in `C1=owner/repo
GITHUB_MARKDOWN_UPDATE_TARGETS Optional Exact admin-only write allowlist in alias=owner/repo:path.md form. Repository scopes grant reads only; an empty target list disables Markdown writes.
AI_DEV_TEAM_BASE_URL Optional Internal base URL for a separate AI Dev Team addon service.
AI_DEV_TEAM_INTERNAL_TOKEN Optional Bearer token AI Team uses when calling the AI Dev Team addon.
AI_DEV_TEAM_WEB_URL Optional Public web UI URL included in Slack status messages.
AI_DEV_TEAM_REPO_CHANNEL_SCOPES Required for persona create/promote Separate action allowlist in `C1=owner/repo
AI_TEAM_TIMEZONE Optional Workspace timezone used for local-day estimated-usage boundaries and kickoffs. Defaults to UTC; DST days use their real 23/25-hour UTC interval.
AI_TEAM_DAILY_BUDGET_USD Optional Soft estimated runtime-model threshold. Defaults to 3; this is not a provider billing cap.
AI_TEAM_MAX_PERSONAS_PER_EVENT Optional Max teammates selected per event. Defaults to 5.
AI_TEAM_WEB_SEARCH_ENABLED Optional Enable public web/source reading. Defaults to false. A persona must also have the relevant tool.
AI_TEAM_EXPERT_CONSULT_ENABLED Optional Expose configured expert-consult model calls to eligible personas. Defaults to false.
AI_TEAM_BUILD_TARGET Compose only Docker build target: runtime (default, no Playwright/Chromium) or opt-in browser.
AI_TEAM_WEB_CAPTURE_ENABLED Optional Expose and enable browser screenshot capture. Defaults to false; also requires the browser image target or Python browser extra.
AI_TEAM_MAX_IMAGE_BYTES Optional Maximum Slack image upload size accepted for vision analysis. Defaults to 10000000.
AI_TEAM_AUTOMATIONS_ENABLED Optional Enable confirmed scheduled checks/watchers. Defaults to false.
AI_TEAM_AUTOMATION_TIMEZONE Optional Default timezone for human schedule parsing. Defaults to UTC.
AI_TEAM_MEMORY_CURATOR_ENABLED Optional Let model-based curation inspect ordinary human messages/thread excerpts and persist selected decision-grade channel memory or project docs. Defaults to false; explicit remember/update commands remain available when it is off.
AI_TEAM_CASTING_FEEDBACK_ENABLED Optional Send multi-person Slack rounds to AI_TEAM_UTILITY_MODEL for contribution scoring. Defaults to false.

Browser capture defaults off in both settings and the supplied .env.example; disabled means its persona tool is neither exposed nor executed. The starter also pins its router and utility model to OpenAI, leaves the explicit fallback list empty, and disables casting feedback, web search, automations, expert consultation and automatic memory curation. Review and configure each optional feature's provider, storage, network and approval requirements before enabling it.

Estimated runtime-model budget

AI_TEAM_DAILY_BUDGET_USD is a best-effort preflight threshold over usage that AI Team has estimated and recorded for the current AI_TEAM_TIMEZONE calendar day. When the recorded estimate is already at or above the threshold, the app does not start a new normal Slack turn, automation model run, daily-kickoff model round, AI Dev Team terminal-report draft or image-generation request.

It is deliberately not described as a hard spend cap. A call that starts below the threshold can finish above it, and concurrent/in-flight turns can overshoot. Provider billing can drift from the local pricing table; unknown or unpriced models can record $0; and some tool, retry or continuation accounting can be incomplete. Embedding calls are outside this guardrail, including repository embeddings started through the protected operator-only /internal/ingest-repos endpoint. Configure provider-side billing alerts/quotas separately.

Successful image generation records zero tokens plus the fixed AI_TEAM_IMAGE_ESTIMATED_COST_USD estimate and explicit estimate metadata.

Never commit real secrets. Use .env locally and a secret manager in production.

Slack App

AI Team implements Slack's HTTPS Events API and interactive-component callback. It does not implement Socket Mode and does not use a Slack app-level token.

  1. Create a blank Slack app from scratch, copy its signing secret into .env, then start AI Team and its public HTTPS proxy/tunnel. This avoids the circular dependency between obtaining a signing secret and Slack verifying a signed Events API challenge.
  2. Copy slack-app-manifest.yaml, replace both example origins, open App Manifest on that existing app, and apply the YAML.
  3. Review the scopes and install it to the workspace. Put the resulting bot token and allowed channel ID in .env, then restart AI Team. Never put bot tokens or the signing secret in the manifest.
  4. In Event Subscriptions, confirm Slack verifies https://<service>/slack/events. In Interactivity & Shortcuts, confirm https://<service>/slack/interactions.
  5. Invite the bot to the boardroom and each channel listed in SLACK_ALLOWED_CHANNEL_IDS.

The included manifest subscribes only to message.channels and message.groups. Message deletion arrives as a message subtype; there is no separate message.deleted subscription. The baseline deliberately omits file_shared: the runtime does not dispatch that event, and retaining it would collect file metadata without providing a working feature.

The baseline callback settings are:

  • Event Request URL: https://<service>/slack/events
  • Interaction URL: https://<service>/slack/interactions
  • Bot scopes: chat:write, chat:write.customize, channels:history, groups:history.
  • Add channels:read, channels:manage and channels:join if you want the app to create, rename or manage configured public channels.
  • Invite the app bot to each allowed channel.

File handling is opt-in. Add files:read only when you intend to analyze image attachments included in allowed-channel message events. Add files:write only when AI Team should upload browser screenshots or generated artifacts back to Slack. Reinstall the Slack app after changing scopes. Do not add a standalone file_shared subscription; attachment handling is driven by the allowed message.* event and must remain within the channel allow-list.

The app posts as separate teammates by setting display names and icons per message through Slack's chat:write.customize scope.

Slack must reach both endpoints over HTTPS with a valid public certificate. Put the app behind a reverse proxy or managed ingress that preserves the request body and Slack signature headers. Do not expose internal maintenance endpoints without a strong AI_TEAM_INTERNAL_TOKEN and network-level access controls.

AI Dev Team Addon

AI Team can bridge Slack requests into a separate AI Dev Team coding runtime. The coding runtime does not need its own Slack app: this service receives Slack events and interactions, renders approval/status messages, and calls the addon through its internal HTTP API.

Set AI_DEV_TEAM_BASE_URL and AI_DEV_TEAM_INTERNAL_TOKEN to enable requests such as "get our dev team to work on repo owner/name ...", status checks, and approval/deny/abort buttons in Slack.

Before allowing a persona to create or promote jobs, set a separate exact action scope, for example AI_DEV_TEAM_REPO_CHANNEL_SCOPES=C1=owner/repo|owner/other;C2=org/repo. This scope never inherits GITHUB_REPOS, channel profiles or GITHUB_REPO_CHANNEL_SCOPES: those are read/index permissions, not coding-agent action authority. Wildcards are rejected. An empty action scope leaves status for channel-provenance jobs available but disables persona creation and Slack promotion.

Set AI_TEAM_ADMIN_SLACK_USER_IDS before enabling the addon. Creating jobs is approval-gated, and only those Slack users can approve, deny or abort jobs. Approve and deny buttons bind both the job UUID and the immutable approval UUID returned by AI Dev Team; abort remains bound only to the job UUID. Legacy, malformed, cross-action, or stale button values fail closed and ask the admin to refresh status. A direct text command containing only a job UUID performs one status read, accepts only a pending_approval job with a non-action pendingApproval, and submits that exact approval UUID once. It never retries a 409 against a newer approval.

Status and list paths verify the authoritative ai_team.job or session.promoted origin event from each detailed job response before showing it in a Slack channel. Global list records are never displayed without that bounded detail check. Free-text approve, deny and abort commands also verify channel provenance before mutation. Structured buttons remain bound to the verified Slack message that rendered them; approve/deny use the embedded exact approval UUID without a reload or retry.

Only personas with ai_dev_team in their tools: list can call the addon as a private tool. Treat it as an action tool, not a read-only context tool: the example config limits it to technical implementation owners. Personas cannot message/steer, approve, deny or abort coding jobs and cannot disable the approval gate. The configured Slack admins and the AI Dev Team service remain trusted; these application checks are not a hard multi-tenant boundary.

GitHub App

Install a GitHub App on repositories listed in GITHUB_REPOS.

Repository permissions:

  • Metadata: read-only.
  • Contents: read-only for repository context.
  • Contents: read and write only when exact Markdown targets are deliberately enabled.

GITHUB_REPOS and per-channel scopes grant reads only. Writes require an exact GITHUB_MARKDOWN_UPDATE_TARGETS entry, an explicit Slack request and a user in AI_TEAM_ADMIN_SLACK_USER_IDS; an empty target list disables writes. To prevent ordinary discussion from becoming a write, the affirmative request must end with the literal line CONFIRM GITHUB WRITE. GitHub rejects the update if the target changed while the model prepared its draft.

Database

The app uses Postgres with pgvector for durable memory, Slack history, repo chunks, artifact metadata and usage logs. The container entrypoint applies every numbered file under migrations/ in order and records its SHA-256 checksum in ai_team_schema_migrations. Concurrent replicas serialize migration startup; editing an already-applied migration fails closed.

Retrieved memories are channel-scoped. Legacy or manually inserted agent_memories rows with no metadata.slack_channel_id are excluded from channel context by default; use the explicit "slack_channel_id": "*" marker only for memory intentionally shared with every channel.

For an externally managed database, install the pgvector extension and give the migration role permission to run CREATE EXTENSION IF NOT EXISTS vector, or preinstall it as a database administrator. To apply migrations through the app entrypoint before serving:

DATABASE_URL=postgresql://... CONFIG_PATH=my-config python -m ai_team.entrypoint

CONFIG_PATH/context-pack.md is a bootstrap seed. On startup, the service inserts it into team_docs using the keys configured in team.yaml, only if that doc does not already exist. Later edits to the bootstrap file do not overwrite the live document; use an explicit update or reset the memory scope.

Development

python -m venv .venv
. .venv/bin/activate
python -m pip install pip==26.1.2
python -m pip install --require-hashes -r requirements-dev.lock
python -m pip install --no-deps --no-build-isolation -e .
CONFIG_PATH=config/default python -m pytest -q

The published container installs the hashed requirements.lock; development uses the hashed requirements-dev.lock. The .txt files and pyproject.toml remain the human-maintained dependency inputs.

Run locally without Docker:

CONFIG_PATH=config/default uvicorn ai_team.main:app --reload --port 8080

Running uvicorn directly is useful for tests against an already migrated database. For a new database, run python -m ai_team.entrypoint once so the migration gate executes.

Technical Architecture

AI Team architecture

See docs/architecture.md for runtime architecture, endpoints, storage, tools, deployment and roadmap details.

Deployed Example

Politikkradar uses AI Team as one deployed configuration for Borge Labs. The framework itself is domain-agnostic: each organization supplies its own config, personas, repositories, memory rules and operating context.

In Borge Labs' own delivery loop, the deployed AI Team configuration handles the Slack-facing work: teammates triage requests, draft specifications, file and consume work-queue issues, and relay human approvals. Implementation runs in a separate supervised pipeline, not in this repository. A supervised multi-agent delivery loop describes that operating model.

The dogfooding case study describes what daily internal use did and did not validate without publishing private workspace content. See the research release notes for the bounded release scope.

Support

There is no support SLA or committed roadmap. Read SUPPORT.md before deploying; forks are welcome, while issues and pull requests are handled best-effort.

Safety Scan

python3 scripts/precommit_scan.py --all

The safety scan checks for credential-looking values and placeholder private keys. It is a lightweight guard, not a substitute for a dedicated secret scanner before publishing.

About Borge Labs

AI Team is built by Borge Labs, an independent Norwegian AI systems lab and product studio. It coordinates the AI staff behind our products and can hand approved coding jobs to its sibling project AI Dev Team, a developer-team runtime for supervised coding agents:

  • Politikkradar - source-grounded monitoring of Norwegian politics for newsrooms and elected officials.
  • Ordrett - verbatim Norwegian speech-to-text.

License

MIT. See LICENSE.

About

Slack-native AI staff for small teams: named AI teammates with roles, models, memory and tools, coordinated by a chair persona. Config-first, self-hosted.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors