@thinkai/tai-api-contract 2.34.0-pr.810.e54f7dcd → 2.34.0

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.
@@ -3209,12 +3209,33 @@ paths:
3209
3209
  description: >
3210
3210
  Paginated, chronological feed of workspace-scoped lifecycle events: repository add/remove/re-add
3211
3211
  and GitHub integration add/remove. Inactive repos remain visible in this log.
3212
- Filter by `eventType`, `actorUserId`, or date range (`since`/`until`).
3212
+ Filter by a single `eventType`, a coarse `eventCategory`/`productArea`, an `eventSubcategory`
3213
+ (a dotted event-type prefix that matches a whole lifecycle subgroup in one call, e.g.
3214
+ `integrations.cursor.execution_key`), `actorUserId`, or date range (`since`/`until`).
3213
3215
  parameters:
3214
3216
  - $ref: "#/components/parameters/WorkspaceId"
3215
3217
  - $ref: "#/components/parameters/PaginationLimit"
3216
3218
  - $ref: "#/components/parameters/PaginationOffset"
3217
3219
  - $ref: "#/components/parameters/PaginationOrder"
3220
+ - name: sort
3221
+ in: query
3222
+ required: false
3223
+ description: >
3224
+ Server-side sort column (the activity "5 W's"). Combined with `order` (asc/desc).
3225
+ Defaults to `when` (occurredAt). `occurredAt`/`id` is always the tiebreaker.
3226
+ schema:
3227
+ type: string
3228
+ enum: [when, who, what, why, where]
3229
+ - name: productArea
3230
+ in: query
3231
+ required: false
3232
+ description: >
3233
+ Coarse product-area grouping filter (#156). `integration` = GitHub + AI-tool key events;
3234
+ `agentic_foundation` = repos, readiness scans, fixes; `workspace_team` = members + HRIS;
3235
+ `productivity` = productivity ingest lifecycle events. Omit (or pass `all`) for every area.
3236
+ schema:
3237
+ type: string
3238
+ enum: [integration, agentic_foundation, workspace_team, productivity, all]
3218
3239
  - name: eventType
3219
3240
  in: query
3220
3241
  description: Filter to a specific event type.
@@ -3245,6 +3266,20 @@ paths:
3245
3266
  Filter by event namespace prefix (e.g. "fix", "repo", "integration", "readiness", "config", "member").
3246
3267
  schema:
3247
3268
  type: string
3269
+ - name: eventSubcategory
3270
+ in: query
3271
+ required: false
3272
+ description: >
3273
+ Filter by a dotted event-type *subgroup* (#156): a strict prefix of an event type with one
3274
+ or more segments (shorter than the full event type), matching every lifecycle event under it
3275
+ in a single call. Single-segment values (e.g. `fix`, `readiness`, `repo`, `productivity`)
3276
+ overlap with `eventCategory` so the same control can filter at any depth. Example:
3277
+ `integrations.cursor.execution_key` returns `integrations.cursor.execution_key.added`,
3278
+ `.updated`, `.removed`, and `.check_failed`; `integrations.cursor` returns all Cursor key
3279
+ events; `fix` returns all fix lifecycle events. Must be one of the known subcategories or the
3280
+ request is rejected (400).
3281
+ schema:
3282
+ type: string
3248
3283
  - name: search
3249
3284
  in: query
3250
3285
  required: false
@@ -3278,6 +3313,100 @@ paths:
3278
3313
  schema:
3279
3314
  $ref: "#/components/schemas/ErrorMessageDto"
3280
3315
 
3316
+ /workspaces/{workspaceId}/activity/export:
3317
+ get:
3318
+ tags: [WorkspaceActivity]
3319
+ summary: Export workspace activity log as CSV
3320
+ operationId: exportWorkspaceActivity
3321
+ description: >
3322
+ Export the workspace activity log as an RFC 4180 CSV file (one row per event). Accepts the
3323
+ same filters as `GET /workspaces/{workspaceId}/activity` (`eventType`, `eventCategory`,
3324
+ `eventSubcategory`, `productArea`, `actorUserId`, `since`, `until`, `search`, `sort`, `order`);
3325
+ `limit`/`offset` are ignored — the export returns up to 50000 matching rows within the sort.
3326
+ Columns: occurredAt, eventType, eventCategory, actorType, actorName, actorEmail, repoName,
3327
+ integrationType, metadata. Opaque internal identifiers (actorUserId, repoId, integrationId,
3328
+ fixRequestId, issueId, readinessRunId) are omitted — the human-readable equivalents are
3329
+ already present and the IDs carry no value in a user-facing export.
3330
+ The response sets `Content-Disposition: attachment` with a `.csv` filename.
3331
+ parameters:
3332
+ - $ref: "#/components/parameters/WorkspaceId"
3333
+ - name: sort
3334
+ in: query
3335
+ required: false
3336
+ schema:
3337
+ type: string
3338
+ enum: [when, who, what, why, where]
3339
+ - $ref: "#/components/parameters/PaginationOrder"
3340
+ - name: productArea
3341
+ in: query
3342
+ required: false
3343
+ schema:
3344
+ type: string
3345
+ enum: [integration, agentic_foundation, workspace_team, productivity, all]
3346
+ - name: eventType
3347
+ in: query
3348
+ required: false
3349
+ schema:
3350
+ $ref: "#/components/schemas/ActivityLogEventTypeDto"
3351
+ - name: eventCategory
3352
+ in: query
3353
+ required: false
3354
+ schema:
3355
+ type: string
3356
+ - name: eventSubcategory
3357
+ in: query
3358
+ required: false
3359
+ description: Dotted event-type subgroup prefix (see the activity list endpoint).
3360
+ schema:
3361
+ type: string
3362
+ - name: actorUserId
3363
+ in: query
3364
+ required: false
3365
+ schema:
3366
+ type: string
3367
+ format: uuid
3368
+ - name: since
3369
+ in: query
3370
+ required: false
3371
+ schema:
3372
+ type: string
3373
+ format: date-time
3374
+ - name: until
3375
+ in: query
3376
+ required: false
3377
+ schema:
3378
+ type: string
3379
+ format: date-time
3380
+ - name: search
3381
+ in: query
3382
+ required: false
3383
+ schema:
3384
+ type: string
3385
+ maxLength: 200
3386
+ responses:
3387
+ "200":
3388
+ description: CSV file of activity log entries
3389
+ content:
3390
+ text/csv:
3391
+ schema:
3392
+ type: string
3393
+ "400":
3394
+ description: Invalid query parameters
3395
+ content:
3396
+ application/json:
3397
+ schema:
3398
+ $ref: "#/components/schemas/ErrorMessageDto"
3399
+ "401":
3400
+ $ref: "#/components/responses/Unauthorized"
3401
+ "403":
3402
+ $ref: "#/components/responses/Forbidden"
3403
+ "404":
3404
+ description: Workspace does not exist
3405
+ content:
3406
+ application/json:
3407
+ schema:
3408
+ $ref: "#/components/schemas/ErrorMessageDto"
3409
+
3281
3410
  /workspaces/{workspaceId}/readiness/score-history:
3282
3411
  get:
3283
3412
  tags: [RepositoryReadiness]
@@ -4045,6 +4174,130 @@ paths:
4045
4174
  "403":
4046
4175
  $ref: "#/components/responses/Forbidden"
4047
4176
 
4177
+ /workspaces/{workspaceId}/repo-eligibility:
4178
+ get:
4179
+ tags: [RepositoryReadiness]
4180
+ summary: Get repo-sync eligibility gate (defaults + per-workspace overrides)
4181
+ description: >
4182
+ Returns the effective repo-sync eligibility gate (archived / fork / size / count) for the
4183
+ workspace: the global `defaults`, any per-workspace `overrides`, the merged `effective`
4184
+ values, and whether the caller can edit without platform-admin (`canEditUnrestricted`).
4185
+ Member-level read access.
4186
+ operationId: getWorkspaceRepoEligibility
4187
+ parameters:
4188
+ - $ref: "#/components/parameters/WorkspaceId"
4189
+ responses:
4190
+ "200":
4191
+ description: Effective repo-eligibility configuration
4192
+ content:
4193
+ application/json:
4194
+ schema:
4195
+ $ref: "#/components/schemas/WorkspaceRepoEligibilityDto"
4196
+ "401":
4197
+ $ref: "#/components/responses/Unauthorized"
4198
+ "403":
4199
+ $ref: "#/components/responses/Forbidden"
4200
+ put:
4201
+ tags: [RepositoryReadiness]
4202
+ summary: Set per-workspace repo-sync eligibility overrides
4203
+ description: >
4204
+ Set (or clear, with an empty `overrides`) the per-workspace repo-sync eligibility overrides.
4205
+ **Platform admins** may set any value (raise caps, `0` = unlimited, include archived/forks).
4206
+ **Workspace admins** may only make the gate *more restrictive* than the platform defaults
4207
+ (lower caps, exclude archived/forks) — exceeding a platform limit returns `403`
4208
+ (`repo_eligibility_bound_exceeded`). Requires workspace admin or platform admin.
4209
+ operationId: putWorkspaceRepoEligibility
4210
+ parameters:
4211
+ - $ref: "#/components/parameters/WorkspaceId"
4212
+ requestBody:
4213
+ required: true
4214
+ content:
4215
+ application/json:
4216
+ schema:
4217
+ type: object
4218
+ required: [overrides]
4219
+ properties:
4220
+ overrides:
4221
+ $ref: "#/components/schemas/RepoEligibilityOverridesDto"
4222
+ responses:
4223
+ "200":
4224
+ description: Overrides saved
4225
+ content:
4226
+ application/json:
4227
+ schema:
4228
+ type: object
4229
+ required: [overrides, effective]
4230
+ properties:
4231
+ overrides:
4232
+ $ref: "#/components/schemas/RepoEligibilityOverridesDto"
4233
+ effective:
4234
+ $ref: "#/components/schemas/RepoEligibilityConfigDto"
4235
+ "400":
4236
+ description: Invalid request body
4237
+ content:
4238
+ application/json:
4239
+ schema:
4240
+ $ref: "#/components/schemas/ErrorMessageDto"
4241
+ "401":
4242
+ $ref: "#/components/responses/Unauthorized"
4243
+ "403":
4244
+ description: Forbidden, or a workspace-admin value exceeds a platform limit (`repo_eligibility_bound_exceeded`)
4245
+ content:
4246
+ application/json:
4247
+ schema:
4248
+ $ref: "#/components/schemas/ErrorMessageDto"
4249
+
4250
+ /workspaces/{workspaceId}/repo-eligibility/refresh-languages:
4251
+ post:
4252
+ tags: [RepositoryReadiness]
4253
+ summary: Force a language/stack re-detection on the next sync
4254
+ description: >
4255
+ Admin maintenance action: invalidate the cached language/stack freshness marker so the
4256
+ next GitHub repo sync re-fetches `GET /repos/{owner}/{repo}/languages` and recomputes the
4257
+ per-language breakdown and supported stacks. Use after adding a newly-supported language
4258
+ to a repo, or when a repo's stack detection looks stale. Optionally scope to a single repo
4259
+ via `repoSlug` (`owner/name`); omit it to reset every repo in the workspace. Requires
4260
+ workspace admin or platform admin. The refresh itself happens on the next sync (e.g. when
4261
+ the GitHub repo list is loaded with `refresh=true`); the readiness scan also refreshes the
4262
+ breakdown on each successful run.
4263
+ operationId: refreshWorkspaceRepoLanguages
4264
+ parameters:
4265
+ - $ref: "#/components/parameters/WorkspaceId"
4266
+ requestBody:
4267
+ required: false
4268
+ content:
4269
+ application/json:
4270
+ schema:
4271
+ type: object
4272
+ properties:
4273
+ repoSlug:
4274
+ type: string
4275
+ description: Optional `owner/name` to scope the refresh to a single repo. Omit to reset all repos.
4276
+ responses:
4277
+ "200":
4278
+ description: Freshness invalidated; languages will be re-detected on the next sync.
4279
+ content:
4280
+ application/json:
4281
+ schema:
4282
+ type: object
4283
+ required: [ok, reposReset]
4284
+ properties:
4285
+ ok:
4286
+ type: boolean
4287
+ reposReset:
4288
+ type: integer
4289
+ description: Number of repo rows whose language/stack cache was invalidated.
4290
+ "400":
4291
+ description: Invalid request body
4292
+ content:
4293
+ application/json:
4294
+ schema:
4295
+ $ref: "#/components/schemas/ErrorMessageDto"
4296
+ "401":
4297
+ $ref: "#/components/responses/Unauthorized"
4298
+ "403":
4299
+ $ref: "#/components/responses/Forbidden"
4300
+
4048
4301
  /workspaces/{workspaceId}/readiness/cursor-key-usage:
4049
4302
  get:
4050
4303
  tags: [RepositoryReadiness]
@@ -5732,16 +5985,6 @@ components:
5732
5985
  type: number
5733
5986
  failRatePercent:
5734
5987
  type: number
5735
- description: DORA change failure rate (deployments/incidents), not CI build failures.
5736
- ciFailRatePercent:
5737
- type: number
5738
- description: >
5739
- GitHub Actions / Checks CI build failure rate for the week bucket
5740
- (failed runs / (failed + passed) * 100). Zero when GitHub Actions CI is disabled.
5741
- ciBuildFailuresCount:
5742
- type: integer
5743
- minimum: 0
5744
- description: Count of build.failed events in the week bucket when CI ingest is enabled.
5745
5988
  avgReviewWaitHours:
5746
5989
  type: number
5747
5990
  description: Mean hours from PR creation to first review in this week bucket.
@@ -5801,9 +6044,6 @@ components:
5801
6044
  generatedAt:
5802
6045
  type: string
5803
6046
  format: date-time
5804
- githubActionsCiEnabled:
5805
- type: boolean
5806
- description: True when the workspace has opted in to GitHub Actions CI ingest.
5807
6047
  teams:
5808
6048
  type: array
5809
6049
  items:
@@ -5897,9 +6137,6 @@ components:
5897
6137
  avgFailRatePercent:
5898
6138
  type: number
5899
6139
  description: Average change failure rate over the range when available.
5900
- avgCiFailRatePercent:
5901
- type: number
5902
- description: Average GitHub Actions CI build failure rate over the range when CI ingest is enabled.
5903
6140
 
5904
6141
  ProductivityInsightsTeamSummaryDto:
5905
6142
  type: object
@@ -5912,10 +6149,6 @@ components:
5912
6149
  type: number
5913
6150
  avgFailRatePercent:
5914
6151
  type: number
5915
- description: Average DORA change failure rate over the range when available.
5916
- avgCiFailRatePercent:
5917
- type: number
5918
- description: Average GitHub Actions CI build failure rate over the range when CI ingest is enabled.
5919
6152
  headcount:
5920
6153
  type: integer
5921
6154
  minimum: 0
@@ -5976,9 +6209,6 @@ components:
5976
6209
  generatedAt:
5977
6210
  type: string
5978
6211
  format: date-time
5979
- githubActionsCiEnabled:
5980
- type: boolean
5981
- description: True when the workspace has opted in to GitHub Actions CI ingest.
5982
6212
  items:
5983
6213
  type: array
5984
6214
  description: Present when `teamId` query is omitted — top-ranked teams.
@@ -6100,10 +6330,6 @@ components:
6100
6330
  minimum: 0
6101
6331
  avgFailRate:
6102
6332
  type: number
6103
- description: Average DORA change failure rate over the range when available.
6104
- avgCiFailRate:
6105
- type: number
6106
- description: Average GitHub Actions CI build failure rate over the range when CI ingest is enabled.
6107
6333
  mergedPrDelta:
6108
6334
  type: number
6109
6335
  avgMergedPrsPerWeekDelta:
@@ -6112,9 +6338,6 @@ components:
6112
6338
  type: number
6113
6339
  avgFailRateDelta:
6114
6340
  type: number
6115
- avgCiFailRateDelta:
6116
- type: number
6117
- description: Change in average CI build failure rate vs the prior comparison window.
6118
6341
 
6119
6342
  ProductivityInsightsContributorDetailDto:
6120
6343
  type: object
@@ -6146,9 +6369,6 @@ components:
6146
6369
  generatedAt:
6147
6370
  type: string
6148
6371
  format: date-time
6149
- githubActionsCiEnabled:
6150
- type: boolean
6151
- description: True when the workspace has opted in to GitHub Actions CI ingest.
6152
6372
  contributor:
6153
6373
  $ref: "#/components/schemas/ProductivityInsightsContributorProfileDto"
6154
6374
  weeks:
@@ -6185,9 +6405,6 @@ components:
6185
6405
  avgFailRatePercent:
6186
6406
  type: number
6187
6407
  description: Mean weekly change-failure rate when available.
6188
- avgCiFailRatePercent:
6189
- type: number
6190
- description: Mean weekly GitHub Actions CI build failure rate when CI ingest is enabled.
6191
6408
 
6192
6409
  ProductivityInsightsNeedsAttentionDto:
6193
6410
  type: object
@@ -6207,9 +6424,6 @@ components:
6207
6424
  generatedAt:
6208
6425
  type: string
6209
6426
  format: date-time
6210
- githubActionsCiEnabled:
6211
- type: boolean
6212
- description: True when GitHub Actions CI ingest is enabled for this workspace.
6213
6427
  items:
6214
6428
  type: array
6215
6429
  items:
@@ -6843,6 +7057,195 @@ components:
6843
7057
  format: date-time
6844
7058
  nullable: true
6845
7059
  description: Last push or metadata update from GitHub when available.
7060
+ archived:
7061
+ type: boolean
7062
+ nullable: true
7063
+ description: True when the repository is archived (read-only on GitHub).
7064
+ fork:
7065
+ type: boolean
7066
+ nullable: true
7067
+ description: True when the repository is a fork of another repository.
7068
+ disabled:
7069
+ type: boolean
7070
+ nullable: true
7071
+ description: True when the repository is disabled on GitHub.
7072
+ size:
7073
+ type: integer
7074
+ nullable: true
7075
+ description: Repository size in KB as reported by GitHub.
7076
+ ineligibleReasons:
7077
+ type: array
7078
+ nullable: true
7079
+ items:
7080
+ type: string
7081
+ description: >
7082
+ Hard structural reasons this repo cannot be analyzed (archived, disabled, too-large,
7083
+ workspace repo cap). Each entry is a human-readable explanation (e.g. "This repo is
7084
+ archived"). Empty or absent means no hard block. Forks and unsupported-language repos
7085
+ are NOT listed here — they are advisory `warnings` (#729) and remain analyzable.
7086
+ warnings:
7087
+ type: array
7088
+ nullable: true
7089
+ items:
7090
+ type: string
7091
+ description: >
7092
+ Non-blocking advisories shown alongside an otherwise-analyzable repo (#729). Includes
7093
+ forks ("results reflect the forked code") and repos with no v1-supported stack, where
7094
+ the message embeds the GitHub language mix in percent. Absent/empty when there are no
7095
+ warnings. Unlike `ineligibleReasons`, warnings do NOT disable analyze/score/fix actions.
7096
+ eligibilityStatus:
7097
+ type: string
7098
+ enum: [eligible, ineligible]
7099
+ nullable: true
7100
+ description: >
7101
+ Whether the repo can be analyzed (issue #44/#729). `ineligible` only for HARD
7102
+ structural gates (archived, disabled, too-large, workspace repo cap) — such repos render
7103
+ read-only in the AF list. A repo with no supported stack or that is a fork is `eligible`
7104
+ and carries a non-blocking `warnings` entry instead of being blocked.
7105
+ eligibilityReason:
7106
+ type: string
7107
+ nullable: true
7108
+ description: >
7109
+ Human-readable explanation when `eligibilityStatus` is `ineligible` (e.g. "This repo
7110
+ is archived"). For advisory language/fork notices see `warnings`, not this field.
7111
+ primaryStack:
7112
+ type: string
7113
+ nullable: true
7114
+ description: >
7115
+ Dominant supported stack (by GitHub language bytes), one of
7116
+ backend_jvm | ios_app | web_spa | backend_go | backend_python. Null when no supported
7117
+ stack was detected.
7118
+ secondaryStack:
7119
+ type: string
7120
+ nullable: true
7121
+ description: Second supported stack for a multi-stack repo, or null.
7122
+ supportedStacks:
7123
+ type: array
7124
+ nullable: true
7125
+ items:
7126
+ type: string
7127
+ description: >
7128
+ All supported stacks detected for the repo (ordered, primary first). Empty/null
7129
+ when no supported stack is present. Drives multi-stack scanning and the orange
7130
+ mixed-monorepo box in the AF UI.
7131
+ languageBreakdown:
7132
+ type: array
7133
+ nullable: true
7134
+ description: >
7135
+ Per-language share of the repo from GitHub's `GET /repos/{owner}/{repo}/languages`
7136
+ byte counts, ordered by share descending (#729). Powers the "language mix" shown in
7137
+ the unsupported-stack warning. Absent/null until the repo has been synced with a
7138
+ language resolver.
7139
+ items:
7140
+ type: object
7141
+ required: [language, percent, supported]
7142
+ properties:
7143
+ language:
7144
+ type: string
7145
+ description: GitHub language name (e.g. "TypeScript", "Go").
7146
+ percent:
7147
+ type: number
7148
+ format: float
7149
+ description: >
7150
+ Share of total language bytes, rounded to four decimal places (e.g. 64.2153). The
7151
+ extra precision keeps small/near-tied languages distinguishable for a hover tag;
7152
+ render it rounded for compact labels. May not sum to exactly 100 due to rounding.
7153
+ supported:
7154
+ type: boolean
7155
+ description: >
7156
+ True when this language maps to a v1-supported stack; false when the language
7157
+ is not supported. Lets the UI flag exactly which languages are not (fully)
7158
+ supported in a mixed/monorepo.
7159
+ stack:
7160
+ type: string
7161
+ nullable: true
7162
+ description: >
7163
+ The supported stack this language maps to
7164
+ (backend_jvm | ios_app | web_spa | backend_go | backend_python), or null when
7165
+ the language is unsupported.
7166
+
7167
+ RepoEligibilityConfigDto:
7168
+ type: object
7169
+ description: Resolved repo-sync eligibility gate (defaults or effective). All fields present.
7170
+ required: [excludeArchived, excludeForks, maxRepoSizeKb, maxReposPerWorkspace]
7171
+ properties:
7172
+ excludeArchived:
7173
+ type: boolean
7174
+ description: Skip archived repos during GitHub repo sync.
7175
+ excludeForks:
7176
+ type: boolean
7177
+ description: Skip forked repos. Forks are included by default.
7178
+ maxRepoSizeKb:
7179
+ type: integer
7180
+ description: Max repo size in KB (GitHub-reported). 0 = no limit.
7181
+ maxReposPerWorkspace:
7182
+ type: integer
7183
+ description: Max repos materialized per workspace per sync. 0 = no limit.
7184
+
7185
+ RepoEligibilityOverridesDto:
7186
+ type: object
7187
+ additionalProperties: false
7188
+ description: >
7189
+ Per-workspace overrides for the repo-sync eligibility gate. Any field present wins over the
7190
+ global default; omit a field to inherit the default. An empty object clears all overrides.
7191
+ properties:
7192
+ excludeArchived:
7193
+ type: boolean
7194
+ nullable: true
7195
+ excludeForks:
7196
+ type: boolean
7197
+ nullable: true
7198
+ maxRepoSizeKb:
7199
+ type: integer
7200
+ minimum: 0
7201
+ nullable: true
7202
+ maxReposPerWorkspace:
7203
+ type: integer
7204
+ minimum: 0
7205
+ nullable: true
7206
+
7207
+ WorkspaceRepoEligibilityDto:
7208
+ type: object
7209
+ required: [defaults, overrides, effective, canEditUnrestricted]
7210
+ properties:
7211
+ defaults:
7212
+ $ref: "#/components/schemas/RepoEligibilityConfigDto"
7213
+ overrides:
7214
+ $ref: "#/components/schemas/RepoEligibilityOverridesDto"
7215
+ effective:
7216
+ $ref: "#/components/schemas/RepoEligibilityConfigDto"
7217
+ canEditUnrestricted:
7218
+ type: boolean
7219
+ description: True when the caller is a platform admin (may set any value, incl. raising caps).
7220
+
7221
+ RepoEligibilityLimitsDto:
7222
+ type: object
7223
+ additionalProperties: false
7224
+ description: >
7225
+ Effective repo-eligibility limits applied to the GitHub repo list, plus the current count
7226
+ of eligible repos. Lets the UI render per-repo "size / limit" (compare each repo's `size`
7227
+ in `GithubInstalledRepoDto` to `maxRepoSizeKb`) and workspace "N / cap" usage
7228
+ (`eligibleRepoCount` / `maxReposPerWorkspace`).
7229
+ required: [maxRepoSizeKb, maxReposPerWorkspace, excludeArchived, excludeForks, eligibleRepoCount]
7230
+ properties:
7231
+ maxRepoSizeKb:
7232
+ type: integer
7233
+ description: Per-repo size cap in KB (GitHub-reported). 0 = no limit.
7234
+ maxReposPerWorkspace:
7235
+ type: integer
7236
+ description: Max repos that can be eligible per workspace. 0 = no limit.
7237
+ excludeArchived:
7238
+ type: boolean
7239
+ description: Whether archived repos are treated as a hard block.
7240
+ excludeForks:
7241
+ type: boolean
7242
+ description: Whether forked repos are excluded by the sync gate (forks are a warning, not a block).
7243
+ eligibleRepoCount:
7244
+ type: integer
7245
+ minimum: 0
7246
+ description: >
7247
+ Repos currently counting as eligible (eligibilityStatus != "ineligible"), i.e. those that
7248
+ count toward `maxReposPerWorkspace`.
6846
7249
 
6847
7250
  GithubMissingPermissionDto:
6848
7251
  type: object
@@ -7013,6 +7416,14 @@ components:
7013
7416
  allOf:
7014
7417
  - $ref: "#/components/schemas/GithubInstalledRepoListDto"
7015
7418
  description: Paginated merged installation repositories when `installed` is true.
7419
+ eligibilityLimits:
7420
+ nullable: true
7421
+ allOf:
7422
+ - $ref: "#/components/schemas/RepoEligibilityLimitsDto"
7423
+ description: >
7424
+ Effective size/count limits and current eligible-repo usage for the repo list. Present
7425
+ when `installed` is true. Pair with each repo's `size` and `eligibilityStatus` to show
7426
+ "size / limit" and "N / cap" in the UI.
7016
7427
  manageUrl:
7017
7428
  type: string
7018
7429
  format: uri
@@ -7685,10 +8096,8 @@ components:
7685
8096
  type: array
7686
8097
  description: >
7687
8098
  Individual rubric criterion outcomes from the latest successful scan.
7688
- Always present on the single-repo detail endpoint. When the repo has a
7689
- succeeded scan but a dimension was not evaluated (e.g. Section I on older
7690
- runs), the API returns full rubric placeholders with status `blocked`.
7691
- Empty array only when the repo has no succeeded scan yet.
8099
+ Always present on the single-repo detail endpoint; empty array when no
8100
+ scan has completed yet for this dimension.
7692
8101
  items:
7693
8102
  $ref: "#/components/schemas/CriterionDetailDto"
7694
8103
  issues:
@@ -7873,6 +8282,79 @@ components:
7873
8282
  nullable: true
7874
8283
  enum: [github_removed, installation_disconnected, installation_replaced, superseded]
7875
8284
  description: Why the repo was archived. Only present when `archivedAt` is set.
8285
+ eligibilityStatus:
8286
+ type: string
8287
+ enum: [eligible, ineligible]
8288
+ nullable: true
8289
+ description: >
8290
+ Whether the repo can be analyzed (#44/#729). Language support no longer makes a repo
8291
+ `ineligible` — a missing v1-supported stack is surfaced via `warnings` and the repo
8292
+ stays analyzable. It becomes `ineligible` when the most recent scan hit a hard
8293
+ size/file-count limit (e.g. code-size or file-count exceeded): the repo is then
8294
+ restricted here too so this surface matches the GitHub connect list's size gate after
8295
+ the scan. Null until the first sync/scan computes it.
8296
+ eligibilityReason:
8297
+ type: string
8298
+ nullable: true
8299
+ description: >
8300
+ Human-readable explanation when `eligibilityStatus` is `ineligible` (e.g. the size /
8301
+ file-count limit message from the last scan). For advisory language notices see
8302
+ `warnings`.
8303
+ warnings:
8304
+ type: array
8305
+ nullable: true
8306
+ items:
8307
+ type: string
8308
+ description: >
8309
+ Non-blocking advisories for an analyzable repo (#729): no v1-supported stack (with the
8310
+ language mix), and hard-limit run outcomes (code size / file count exceeded) carried from
8311
+ the last run. Absent/empty when there are no warnings.
8312
+ primaryStack:
8313
+ type: string
8314
+ nullable: true
8315
+ description: Dominant supported stack — backend_jvm | ios_app | web_spa | backend_go | backend_python. Null when no supported stack/uncomputed.
8316
+ secondaryStack:
8317
+ type: string
8318
+ nullable: true
8319
+ description: Second supported stack for a multi-stack repo, or null.
8320
+ supportedStacks:
8321
+ type: array
8322
+ nullable: true
8323
+ items:
8324
+ type: string
8325
+ description: All supported stacks detected (ordered, primary first). Empty/null when none.
8326
+ languageBreakdown:
8327
+ type: array
8328
+ nullable: true
8329
+ description: >
8330
+ Per-language share from GitHub languages (#729), ordered by share descending. Each entry
8331
+ has `supported`/`stack` so the UI can tag which languages are (not) supported. Absent
8332
+ until the repo has been synced with a language resolver.
8333
+ items:
8334
+ type: object
8335
+ required: [language, percent, supported]
8336
+ properties:
8337
+ language:
8338
+ type: string
8339
+ percent:
8340
+ type: number
8341
+ format: float
8342
+ description: Share of total language bytes, rounded to four decimal places (e.g. 64.2153).
8343
+ supported:
8344
+ type: boolean
8345
+ stack:
8346
+ type: string
8347
+ nullable: true
8348
+ sizeKb:
8349
+ type: integer
8350
+ nullable: true
8351
+ minimum: 0
8352
+ description: >
8353
+ GitHub-reported repository size in KB (includes git history), refreshed on each readiness
8354
+ scan (#729). Compare against `eligibilityLimits.maxRepoSizeKb` on the list response to show
8355
+ per-repo "size / limit". When the size exceeds the limit the latest scan is recorded as
8356
+ `partial_failed` with `lastRunErrorCode = exceeded_repo_size_limit` and the repo is marked
8357
+ `ineligible`. Null until a scan has populated it.
7876
8358
 
7877
8359
  RepoReadinessScoreDetailDto:
7878
8360
  type: object
@@ -7943,6 +8425,55 @@ components:
7943
8425
  type: string
7944
8426
  nullable: true
7945
8427
  enum: [github_removed, installation_disconnected, installation_replaced, superseded]
8428
+ eligibilityStatus:
8429
+ type: string
8430
+ enum: [eligible, ineligible]
8431
+ nullable: true
8432
+ description: See RepoReadinessScoreDto.eligibilityStatus. Language support is advisory (#729) and surfaced via `warnings`.
8433
+ eligibilityReason:
8434
+ type: string
8435
+ nullable: true
8436
+ warnings:
8437
+ type: array
8438
+ nullable: true
8439
+ items:
8440
+ type: string
8441
+ description: Non-blocking advisories (no v1-supported stack, hard-limit run outcomes). See RepoReadinessScoreDto.warnings.
8442
+ primaryStack:
8443
+ type: string
8444
+ nullable: true
8445
+ secondaryStack:
8446
+ type: string
8447
+ nullable: true
8448
+ supportedStacks:
8449
+ type: array
8450
+ nullable: true
8451
+ items:
8452
+ type: string
8453
+ languageBreakdown:
8454
+ type: array
8455
+ nullable: true
8456
+ description: Per-language share with `supported`/`stack` tags. See RepoReadinessScoreDto.languageBreakdown.
8457
+ items:
8458
+ type: object
8459
+ required: [language, percent, supported]
8460
+ properties:
8461
+ language:
8462
+ type: string
8463
+ percent:
8464
+ type: number
8465
+ format: float
8466
+ description: Share of total language bytes, rounded to four decimal places (e.g. 64.2153).
8467
+ supported:
8468
+ type: boolean
8469
+ stack:
8470
+ type: string
8471
+ nullable: true
8472
+ sizeKb:
8473
+ type: integer
8474
+ nullable: true
8475
+ minimum: 0
8476
+ description: GitHub-reported repository size in KB, refreshed on each scan. See RepoReadinessScoreDto.sizeKb.
7946
8477
 
7947
8478
  AgenticFoundationDashboardSummaryDto:
7948
8479
  type: object
@@ -8006,6 +8537,34 @@ components:
8006
8537
  type: integer
8007
8538
  minimum: 0
8008
8539
 
8540
+ ReadinessEligibilityLimitsDto:
8541
+ type: object
8542
+ additionalProperties: false
8543
+ description: >
8544
+ Effective size/code limits enforced by readiness scans (#729). Lets the UI render per-repo
8545
+ "size / limit" (compare each repo's `sizeKb` to `maxRepoSizeKb`) and explain why a repo is
8546
+ `ineligible` due to a hard size/file-count limit. A repo over `maxRepoSizeKb` is skipped on the
8547
+ next scan (recorded `partial_failed` with `exceeded_repo_size_limit`); code-line/file counts are
8548
+ evaluated post-clone via `cloc`.
8549
+ required: [maxRepoSizeKb, maxLinesOfCode, maxFileCount, maxReposPerWorkspace]
8550
+ properties:
8551
+ maxRepoSizeKb:
8552
+ type: integer
8553
+ minimum: 0
8554
+ description: Per-repo GitHub size cap in KB (includes git history). 0 = no limit.
8555
+ maxLinesOfCode:
8556
+ type: integer
8557
+ minimum: 0
8558
+ description: Max total lines of code (cloc) before a scan is skipped. 0 = no limit.
8559
+ maxFileCount:
8560
+ type: integer
8561
+ minimum: 0
8562
+ description: Max source file count (cloc) before a scan is skipped. 0 = no limit.
8563
+ maxReposPerWorkspace:
8564
+ type: integer
8565
+ minimum: 0
8566
+ description: Max repos that can be eligible per workspace. 0 = no limit.
8567
+
8009
8568
  ReadinessRepoListDto:
8010
8569
  allOf:
8011
8570
  - $ref: "#/components/schemas/PageMetaDto"
@@ -8016,6 +8575,8 @@ components:
8016
8575
  type: array
8017
8576
  items:
8018
8577
  $ref: "#/components/schemas/RepoReadinessScoreDto"
8578
+ eligibilityLimits:
8579
+ $ref: "#/components/schemas/ReadinessEligibilityLimitsDto"
8019
8580
 
8020
8581
  ReadinessRepoDetailListDto:
8021
8582
  description: >
@@ -9003,18 +9564,39 @@ components:
9003
9564
  - readiness.scan_completed
9004
9565
  - readiness.scan_failed
9005
9566
  - readiness.scan_partial
9006
- - config.cursor.added
9007
- - config.cursor.updated
9008
- - config.cursor.removed
9009
- - config.cursor.platform_key_enabled
9010
- - config.cursor.platform_key_disabled
9011
- - config.claude.added
9012
- - config.claude.updated
9013
- - config.claude.removed
9014
- - config.agent_execution.provider_changed
9567
+ - integrations.agent_execution.provider_changed
9568
+ - integrations.repo_eligibility.overrides_changed
9569
+ - integrations.repo_eligibility.languages_refresh_requested
9570
+ - integrations.cursor.platform_key_enabled
9571
+ - integrations.cursor.platform_key_disabled
9015
9572
  - member.invited
9016
9573
  - member.role_changed
9017
9574
  - member.removed
9575
+ - hris.personio.sync_started
9576
+ - hris.personio.sync_completed
9577
+ - hris.personio.sync_failed
9578
+ - hris.sync_started
9579
+ - hris.sync_completed
9580
+ - hris.sync_failed
9581
+ - repo.sync_skipped
9582
+ - integrations.cursor.execution_key.added
9583
+ - integrations.cursor.execution_key.updated
9584
+ - integrations.cursor.execution_key.removed
9585
+ - integrations.cursor.execution_key.check_failed
9586
+ - integrations.cursor.admin_key.added
9587
+ - integrations.cursor.admin_key.updated
9588
+ - integrations.cursor.admin_key.removed
9589
+ - integrations.claude.execution_key.added
9590
+ - integrations.claude.execution_key.updated
9591
+ - integrations.claude.execution_key.removed
9592
+ - integrations.claude.execution_key.check_failed
9593
+ - integrations.claude.admin_key.added
9594
+ - integrations.claude.admin_key.updated
9595
+ - integrations.claude.admin_key.removed
9596
+ - readiness.scan_precheck_failed
9597
+ - productivity.ingest.completed
9598
+ - productivity.ingest.failed
9599
+ - productivity.ingest.skipped
9018
9600
 
9019
9601
  ActivityLogActorDto:
9020
9602
  type: object