Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c33134f
initial research
jp-agenta May 12, 2026
90d9017
initial design
jp-agenta May 13, 2026
71000ee
clean up design
jp-agenta May 13, 2026
da0548d
actually, initial implementation done
jp-agenta May 13, 2026
335ed1f
follow-up implementation
jp-agenta May 14, 2026
b716f56
Merge branch 'release/v0.99.8' into feat/add-access-controls-in-env-vars
jp-agenta May 14, 2026
eef81db
quick fix
jp-agenta May 14, 2026
ba00f60
regenerate fern clients and api references
jp-agenta May 14, 2026
63b6292
Merge feat/clean-up-meters
jp-agenta May 18, 2026
d06bc73
Merge feat/clean-up-meters
jp-agenta May 18, 2026
9b5f235
merge and fix
jp-agenta May 18, 2026
5a3b833
another CR
jp-agenta May 18, 2026
f72853b
Merge branch 'feat/clean-up-meters' into feat/add-access-controls-in-…
jp-agenta May 18, 2026
794d81d
some clean-up
jp-agenta May 18, 2026
0b9ae13
Merge branch 'feat/clean-up-meters' into feat/add-access-controls-in-…
jp-agenta May 18, 2026
73d4aa4
Merge branch 'feat/clean-up-meters' into feat/add-access-controls-in-…
jp-agenta May 18, 2026
2ffe682
fix stripe meters mapping
jp-agenta May 18, 2026
20bbb48
fix stripe conversion and format and drop billing docs
jp-agenta May 18, 2026
4065458
Merge branch 'feat/clean-up-meters' into feat/add-access-controls-in-…
junaway May 19, 2026
4273a36
fix downgrade in migration
jp-agenta May 19, 2026
2edab92
Merge branch 'release/v0.100.0' into feat/add-access-controls-in-env-…
jp-agenta May 19, 2026
6438b22
fix support findongs
jp-agenta May 19, 2026
d10ee9a
add project-scoped roles overlay
jp-agenta May 19, 2026
fd8442a
fix entitlements, endpoints, tabs, and more
jp-agenta May 19, 2026
91a60dd
fix entitlements, endpoints, tabs, docs, and more
jp-agenta May 19, 2026
3badc76
Fix docs and invite flow
jp-agenta May 19, 2026
cf541eb
fix type-related issues
jp-agenta May 19, 2026
0c57b28
copilot CR and comments
jp-agenta May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from oss.src.models.db_models import ProjectDB
from ee.src.models.extended.deprecated_models import DeprecatedOrganizationDB
from ee.src.dbs.postgres.subscriptions.dbes import SubscriptionDBE
from ee.src.core.subscriptions.types import FREE_PLAN

# Historical reference: both `Gauge.APPLICATIONS` and the legacy `Gauge.USERS`
# enum label predate the meters reshape that adds `meter_id`, `workspace_id`,
Expand All @@ -37,6 +36,14 @@
_LEGACY_APPLICATIONS_KEY = "APPLICATIONS"
_LEGACY_USERS_KEY = "USERS"

# Point-in-time literal; the runtime free-plan slug is now resolved via
# `ee.src.core.subscriptions.settings.get_free_plan()`. Operators running
# with a custom `AGENTA_ACCESS_PLANS` set must either keep this slug in
# the effective plan set or declare a `"free": true` entry in
# `AGENTA_BILLING_PRICING`. Startup validation in `settings.py` fails fast
# when neither condition is met.
FREE_PLAN = "cloud_v0_hobby"

stripe.api_key = env.stripe.api_key

log = get_module_logger(__name__)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"""Unify organization_members.role 'member' to 'viewer'

Aligns the organization scope with workspace/project scopes on a single
least-permission role slug. The runtime access-controls layer
(`ee.src.core.entitlements.controls`) treats `viewer` as the per-scope
minima for every scope; this migration brings stored data and the column
default in line with that.

- Rewrites every row with role='member' to role='viewer'.
- Changes the column server default from 'member' to 'viewer'.

The downgrade reverses both, restoring the previous behavior.

Revision ID: a1b2c3d4e5f7
Revises: 9d3e8f0a1b2c
Create Date: 2026-05-13 00:00:00.000000
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy import text


revision: str = "a1b2c3d4e5f7"
down_revision: Union[str, None] = "9d3e8f0a1b2c"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
conn = op.get_bind()

conn.execute(
text("UPDATE organization_members SET role = 'viewer' WHERE role = 'member'")
)

op.alter_column(
"organization_members",
"role",
server_default="viewer",
existing_type=sa.String(),
existing_nullable=False,
)


def downgrade() -> None:
conn = op.get_bind()

op.alter_column(
"organization_members",
"role",
server_default="member",
existing_type=sa.String(),
existing_nullable=False,
Comment thread
jp-agenta marked this conversation as resolved.
)

conn.execute(
text("UPDATE organization_members SET role = 'member' WHERE role = 'viewer'")
)
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,20 @@
import uuid_utils.compat as uuid

from oss.src.utils.env import env
from ee.src.core.subscriptions.types import FREE_PLAN
from sqlalchemy.dialects import postgresql

# Point-in-time literal; the runtime free-plan slug is now resolved via
# `ee.src.core.subscriptions.settings.get_free_plan()`.
#
# Operators running this migration MUST either:
# 1. keep `cloud_v0_hobby` in their effective `AGENTA_ACCESS_PLANS` set, or
# 2. set one entry of `AGENTA_BILLING_PRICING` to `"free": true` so
# `get_free_plan()` resolves without falling back to this literal.
#
# `settings._build_settings()` enforces this at startup; mismatches fail
# loudly rather than silently writing an unknown plan slug.
FREE_PLAN = "cloud_v0_hobby"

# revision identifiers, used by Alembic.
revision: str = "a9f3e8b7c5d1"
down_revision: Union[str, None] = "12d23a8f7dde"
Expand Down Expand Up @@ -402,7 +413,7 @@ def _constraint_exists(constraint_name: str) -> bool:
WHERE s.organization_id = o.id
)
"""),
{"plan": FREE_PLAN.value},
{"plan": FREE_PLAN},
)

# Step 13: Ensure any remaining orgs have flags set
Expand Down
10 changes: 6 additions & 4 deletions api/ee/docker/Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ COPY ./api/ee/src/crons/meters.sh /meters.sh
COPY ./api/ee/src/crons/meters.txt /etc/cron.d/meters-cron
COPY ./api/ee/src/crons/spans.sh /spans.sh
COPY ./api/ee/src/crons/spans.txt /etc/cron.d/spans-cron
COPY ./api/ee/src/crons/events.sh /events.sh
COPY ./api/ee/src/crons/events.txt /etc/cron.d/events-cron

RUN chmod +x /queries.sh /meters.sh /spans.sh \
&& chmod 0644 /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
&& for f in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron; do sed -i -e '$a\' "$f"; done \
&& cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
RUN chmod +x /queries.sh /meters.sh /spans.sh /events.sh \
&& chmod 0644 /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
&& for f in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron; do sed -i -e '$a\' "$f"; done \
&& cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
| sed -E 's/^(([^[:space:]]+[[:space:]]+){5})root[[:space:]]+/\1/' \
| sed 's| >> /proc/1/fd/1 2>&1||' > /app/crontab \
&& chown agenta:agenta /app/crontab
Expand Down
6 changes: 4 additions & 2 deletions api/ee/docker/Dockerfile.gh
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ COPY --chmod=755 ./api/ee/src/crons/meters.sh /meters.sh
COPY --chmod=644 ./api/ee/src/crons/meters.txt /etc/cron.d/meters-cron
COPY --chmod=755 ./api/ee/src/crons/spans.sh /spans.sh
COPY --chmod=644 ./api/ee/src/crons/spans.txt /etc/cron.d/spans-cron
COPY --chmod=755 ./api/ee/src/crons/events.sh /events.sh
COPY --chmod=644 ./api/ee/src/crons/events.txt /etc/cron.d/events-cron

# Copy dependencies from builder
COPY --from=builder /opt/venv /opt/venv
Expand All @@ -112,10 +114,10 @@ COPY --chown=agenta:agenta --from=builder /clients/python /clients/python

# Generate supercronic-compatible crontab (strip user field and /proc redirects)
RUN set -eux; \
for cron_file in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron; do \
for cron_file in /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron; do \
sed -i -e '$a\' "${cron_file}"; \
done; \
cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron \
cat /etc/cron.d/queries-cron /etc/cron.d/meters-cron /etc/cron.d/spans-cron /etc/cron.d/events-cron \
| sed -E 's/^(([^[:space:]]+[[:space:]]+){5})root[[:space:]]+/\1/' \
| sed 's| >> /proc/1/fd/1 2>&1||' > /app/crontab && \
chown agenta:agenta /app/crontab
Expand Down
Loading
Loading