feat: add description to functions, sites, buckets, topics, databases, keys, webhooks and variables by HarshMN2345 · Pull Request #14595 · appwrite/appwrite · GitHub
Skip to content

feat: add description to functions, sites, buckets, topics, databases, keys, webhooks and variables - #14595

Merged
HarshMN2345 merged 13 commits into
mainfrom
claude/descriptions-to-main
Oct 16, 2026
Merged

HarshMN2345 merged 13 commits into
mainfrom
claude/descriptions-to-main

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

What does this PR do?

Gets resource descriptions live. The API params have existed on
feat/description-schema since 14 Oct but never reached main, so production Cloud
still returns no description field on functions, buckets and the rest.

Why it was never live. The two PRs landed in the wrong order:

when (UTC, 14 Oct) what
11:12 #14471 merged feat/description-schema (then just the collection-schema commit) into main
21:55 #14355 merged the actual API params into feat/description-schema — ten hours after its base had already gone

So main got only 33ee90d2f8 ("add the description attribute to the collection
schema"), and the 112 param('description') declarations stayed on a branch that
was by then 7 commits ahead of main. The only param('description') on main
today is the long-standing one in Projects/Http/Projects/Update.php.

This PR merges the branch across and makes it mergeable.

Resolving the merge

git merge conflicted in 51 files, 49 of them under
src/Appwrite/Platform/Modules/Databases/, because main refactored the
attribute and column endpoints after the branch was cut — exactly the surface the
branch rewrites. Every conflict is resolved by keeping main's structure and
applying only the branch's description addition on top
, never by taking the
branch's whole file. The branch was stale on all of these:

the branch's stale side main's current form
Database::VAR_* ColumnType::*->value (and AttributeDefinition::storedType(...))
$dbForProject->getAdapter()->getMaxUIDLength() $dbForProject->getMaxUidLength()
$dbForProject->getAdapter()->get{Min,Max}DateTime() $dbForProject->getAdapter()->limits()->{min,max}DateTime
new Spatial(Database::VAR_LINESTRING) new Spatial(ColumnType::Linestring->value)

Two files needed more than that:

  • src/Appwrite/Utopia/Database/Validator/Indexes.php — main added
    use Utopia\Query\Schema\IndexType; where the branch added
    use Utopia\Validator\Text;. Both are needed and both are kept.
  • tests/e2e/Services/Databases/DatabasesBase.php — git had interleaved the
    branch's five new description tests with three main-only tests added in the same
    region (testCreateCollectionInlineDoubleIgnoresSize,
    testCreateCollectionInlineInternalFiltersAreRefused,
    testCreateCollectionInlineEncryptedString). Since the branch's change to this
    file is purely additive (492 insertions, 0 deletions), the file is rebuilt from
    main's version plus those five tests, ported to main's enums and its
    Id::unique() spelling — the branch's ID::unique() resolves only by PHP's
    case-insensitive alias lookup, and the file uses Id::unique() 334 times.

The branch's two new validator tests are ported the same way, onto
ColumnType/IndexType instead of Database::VAR_*/Database::INDEX_*. The
constant values are identical ('varchar', 'key', ...), so this is consistency
with the surrounding files rather than a behaviour change.

Fixing the 500 on an explicit null

Every description param is optional, and Utopia skips validation entirely for
an optional param whose value is an explicit null:

// Utopia\Http\Http::validate()
if ($param['optional'] && \is_null($value)) {
    return;
}

It then hands that null to the action, because getArguments() falls back to the
declared default only when the key is absent from the request altogether:

$arg = $existsInRequest ? $requestParams[$requestKey] : $param['default'];

So {"description": null} arrives as null whatever the default is. The 58
endpoints
whose action declared a non-nullable string $description raised a
TypeError and returned 500. A validator cannot turn this into a clean 400,
because validation is skipped before the validator is ever consulted.

Fixed the way main already handles this for schedule in
Functions/Http/Functions/Create.php:

->param('schedule', '', new Cron(), '...', true)   // declaration unchanged
?string $schedule,                                  // accepts the null Utopia passes
$schedule ??= '';                                   // null means "not provided"

The param declarations and defaults are left alone, so the generated specs and
SDKs do not change
— only the action signatures and a coalesce. 34 signatures
cover all 58 endpoints; the other 24 are subclasses that re-declare the params and
reuse a parent's action(), such as TablesDB\Create extends Databases\Create.

This also makes create and update consistent. Null means "use what is already
there": on update that is the saved value, on create there is nothing saved yet so
it is the empty default. Only '' ever clears a description, on either path.
The attribute and column update endpoints express the same rule as a guard inside
the shared Attributes\Action::updateAttribute() helper
(if (!\is_null($description))) rather than a coalesce.

Deliberately left out

  • Two pre-existing field-overwrite bugs — keys expire, and webhooks
    security/httpUser/enabled. These update endpoints write their params
    unconditionally, so omitting one resets it to the declared default. They predate
    this work and are not description-related, so they belong in their own PR.
  • Projects/Http/Projects/Update.php — the console project's own pre-existing
    description, which has the same non-nullable signature. Its nine sibling params
    (logo, url, legalName, ...) share both that shape and the unconditional
    overwrite above, so fixing only description there would be half a change. It is
    the one documented exclusion in the new unit test.
  • The same latent null pattern exists widely on main outside this surface —
    entrypoint and commands on Functions/Create.php, for instance, would 500 on
    an explicit null today. Out of scope here.

Test Plan

composer install does not run in this environment, so this was verified with
static checks, the repo's own tooling, and by executing the new test's assertion
directly. Reported honestly, including what could not be run.

Ran and passed:

  • php -l across all 144 changed files — 0 failures.
  • pint --test --config pint.json on all 144 — {"tool":"pint","result":"passed"}.
  • The new unit test's actual assertion, executed. DescriptionParamTest
    reflects over every endpoint declaring an optional description param. Running
    that reflection against all 112 endpoints (0 load errors):
    • with this change: PASS, 0 failing
    • with src/ reverted to the merge commit: FAIL, 58 failing
  • No main content reverted. Every one of the 395 hunks in this PR was audited;
    the 59 that do not mention "description" are all pure additions — 53
    use Utopia\Validator\Text;, 5 use Utopia\Validator\Nullable;, and one new
    updateVariable() e2e helper. Zero removals.
  • Stale-symbol sweep: Database::VAR_, getAdapter()->getMaxUIDLength() and
    getAdapter()->get{Min,Max}DateTime() appear in 0 files under the touched
    trees, confirming no refactor was undone.
  • Spot-check of the largest conflicted file: DatabasesBase.php is
    492 insertions, 0 deletions against main — exactly the branch's additive
    diff, with all three main-only tests intact.
  • Auto-merged files cross-checked against an independent git merge-tree: all
    74 non-conflicted branch-touched files are byte-identical to a clean merge.
  • param('description') count is 113 — the branch's 112 plus the pre-existing
    Projects/Update.php one, which survives (92 Databases, 4 Sites, 4 Project,
    4 Functions, 2 each Webhooks/Storage/Organization/Messaging).
  • git merge-tree origin/main HEAD exits 0: merges cleanly into current main,
    including the packages/queue and packages/usage commits that landed while this
    was being prepared.

Could not run here:

  • PHPUnit. There is no vendor/, and the one sibling checkout with one installed
    predates Utopia\Validator\Validator, so the validator tests cannot be loaded
    against it. The reflection assertion above runs because PHP resolves use
    statements lazily, so action signatures can be read without the validator classes.
  • The e2e suites, which need a live stack. The null-description cases added to
    StorageCustomServerTest::testUpdateBucketDescription and
    FunctionsCustomServerTest assert create-with-null → 201 + '' and
    update-with-null → keeps the saved value.
  • Spec and SDK generation. The repo tracks no spec files; .github/workflows/specs.yml
    generates them in CI. This PR changes no param declaration, so the specs should be
    unaffected either way.

Related PRs and Issues

Checklist

  • Have you read the Contributing Guidelines on issues?
  • If the PR includes a change to an API's metadata (desc, label, params, etc.), does it also include updated API specs and example docs?

The description params are new API metadata, and the branch carries the reference
docs for them. No spec files are committed to this repo — .github/workflows/specs.yml
generates them — and the 500 fix deliberately changes no declaration, only action
signatures, so it does not move the specs.

🤖 Generated with Claude Code

Meldiron and others added 9 commits October 12, 2026 12:23
Optional description on create and update, stored on the functions
collection (1024 chars, default '') and included in search. Mirrors
WAF rule descriptions on Cloud.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Same shape as functions: optional, up to 1024 chars, default '', kept on
update when omitted. Covers sites, function/site/project variables, API
keys, webhooks, databases, tables/collections, columns/attributes (every
type, legacy and TablesDB) and indexes, including inline column and index
definitions on table create. Searchable where the list endpoint supports
search. Description-only variable updates no longer mark functions or
sites for redeploy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bases

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Main added a webhooks case to V25 for httpPass, which shadowed the
webhooks label in the keys case. Move the description step into it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bucket update now also rewrites search, which it never did, so a
renamed bucket was only found by its old name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema half of this PR moved to feat/description-schema so it can merge
first. Merging it here also brings in main; the only conflicts were the topic
`expiry` param rewording next to the new `description` param.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat: add description to functions, sites, variables, keys, webhooks and databases
The API params for resource descriptions were merged into
feat/description-schema by #14355 ten hours after #14471 had already
merged that branch's then-tip into main, so the params never reached
main. This merge brings them across.

51 files conflicted, 49 of them under the Databases module, because main
refactored the attribute/column endpoints after the branch was cut. Every
conflict is resolved by keeping main's structure and applying only the
branch's description addition on top:

  - Database::VAR_* -> ColumnType::*->value (main's enum migration)
  - getAdapter()->getMaxUIDLength() -> getMaxUidLength()
  - getAdapter()->get{Min,Max}DateTime() -> getAdapter()->limits()->{min,max}DateTime
  - new Spatial(Database::VAR_*) -> new Spatial(ColumnType::*->value)

tests/e2e/Services/Databases/DatabasesBase.php is rebuilt from main's
version plus the branch's five new description tests, ported to main's
enums and Id::unique() casing, because git had interleaved the branch's
new tests with three main-only tests added in the same region.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Utopia skips validation for an optional param whose value is an explicit
null, then hands that null to the action rather than the declared default:

    // Utopia\Http\Http::validate()
    if ($param['optional'] && \is_null($value)) {
        return;
    }

    // Utopia\Http\Http::getArguments()
    $arg = $existsInRequest ? $requestParams[$requestKey] : $param['default'];

So `{"description": null}` arrived as null whatever the default was, and the
58 endpoints whose action declared a non-nullable `string $description`
raised a TypeError and returned 500 instead of treating it as not provided.
A validator cannot produce a clean 400 here, because validation is skipped
before the validator is ever consulted.

Fixed the way main already handles this for `schedule` in
Functions/Http/Functions/Create.php: declare `?string $description` and
coalesce to the declared default. The param declarations and defaults are
untouched, so the generated specs and SDKs do not change.

This keeps create and update consistent: null means "use what is already
there", which on create is the empty default and on update is the saved
value, so only '' ever clears a description.

34 action signatures cover all 58 endpoints; the other 24 are subclasses
that re-declare the params and reuse a parent's action(), such as
TablesDB\Create extending Databases\Create.

tests/unit/Platform/DescriptionParamTest.php pins the signature half by
reflecting over every endpoint that declares an optional description param,
discovered from the source so new endpoints are covered too. It reports 58
failures without this change. The behaviour either side of the null is
covered by the bucket and function e2e suites.

Also ports the branch's two new validator tests onto main's enums
(ColumnType/IndexType in place of Database::VAR_*/INDEX_*), matching what
the surrounding files on main already use.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tenki-reviewer

tenki-reviewer Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Review complete. No blocking issues — approved ✅; 3 nitpicks below.

🧹 Nitpicks (3) — 🟢 3 low
  • 🟢 Two-way relationship mirror drops description (Action.php:458) — When a two-way relationship attribute is created, the mirrored attribute document for the related collection omits the description field that the primary document receives (Attributes/Action.php:458-476 vs line 392).
  • 🟢 Replace preg_match with string functions in the test (DescriptionParamTest.php:127) — The new unit test uses preg_match to detect optional description params in endpoint sources (tests/unit/Platform/DescriptionParamTest.php:127).
  • 🟢 Variable descriptions missing from search attribute (Create.php:106) — The new variable description is stored but never included in the search attribute, while this PR appends description to search for functions (Functions/Http/Functions/Create.php:283); the variable create actions keep search as id, resource id, key, and type only (Functions/Http/Variables/Create.php:106).

This PR introduces a user-facing description parameter across the API surface: create endpoints accept it (defaulting to ''), update endpoints treat null as "unchanged", and it is persisted on the underlying metadata documents and included in the computed search attribute for most resources.

Files Change
src/Appwrite/Platform/Modules/Databases/**, src/Appwrite/Utopia/Database/Validator/* Adds description params (Text 1024/0) to attribute/column/index/collection/database create+update endpoints across Databases, DocumentsDB, TablesDB, and VectorsDB, with matching validator support
src/Appwrite/Utopia/Response/Model/*.php Adds an additive description rule (default '') to 15+ response models so older SDKs stay compatible
src/Appwrite/Platform/Modules/{Functions,Sites,Project,Organization,Storage,Webhooks,Messaging}/** Extends functions, sites, project variables, project/org keys, buckets, webhooks, and topics endpoints with the same nullable description handling
app/config/collections/*.php, src/Appwrite/Migration/Version/V25.php Declares the description attribute (size 1024, default '') in collection schemas and the V25 migration backfills existing rows
tests/e2e/**, tests/unit/** Adds e2e coverage for create/update description semantics across services and new unit tests for the param and validators

Reviewed commit: 4805600

@hansi-codes

hansi-codes Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

🔵 Tier A · Mergeable after minor fixes

Limited by an open minor finding: Avoid regex in the endpoint-discovery test

Adds optional descriptions to database resources, functions, sites, buckets, topics, keys, webhooks, and variables, persisting them and exposing them through response models and reference docs. Updates the SDK parameter-order lock and adds validator, unit, and end-to-end coverage for the new fields, while porting database tests to the current schema enums.

Latest changes: The newest commits make create-action description arguments non-nullable again and remove explicit-null create assertions from the Functions and Storage end-to-end tests.

Verdict New comments Fixed Still open
✅ Approved 0 0 2
Fix with agent prompt
### Issue 1
tests/unit/Platform/DescriptionParamTest.php:127
**Avoid regex in the endpoint-discovery test**

This test uses `preg_match` here and again at line 131 to parse endpoint source, but `AGENTS.md` explicitly forbids adding regular expressions. This can also silently miss declarations as their formatting changes; string-based parsing would follow the repository rule.

### Issue 2
src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php:198
**Cover an explicit null on function update**

The function update e2e case checks that omitting `description` preserves the saved value, but never sends `description: null`. Since this new nullable input is meant to preserve the value too, an explicit-null assertion here would catch regressions in this handler; the bucket test exercises a different action.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
📂 Walkthrough · 8
File Change
app/config/sdks/parameters.lock.json Refreshes SDK parameter-order locks for the added description parameters.
src/Appwrite/Platform/Modules/Databases/Http/** Adds descriptions to database resources, collections, indexes, attributes, and tables/columns, including create and update persistence.
src/Appwrite/Platform/Modules/{Functions,Messaging,Organization,Project,Sites,Storage,Webhooks}/Http/** Adds description parameters and persistence for the supported functions, variables, topics, keys, sites, buckets, and webhooks.
src/Appwrite/Utopia/Database/Validator/** Adds description validation and validator tests.
src/Appwrite/Utopia/Response/Model/** Exposes descriptions in resource response models.
docs/** Documents the new description parameters in API reference pages.
tests/e2e/Services/** Adds API coverage for descriptions and updates database tests to the current enum API.
tests/unit/Platform/DescriptionParamTest.php Checks optional description handling across endpoints.
⏳ Still open from earlier reviews · 2
🔇 Filtered out · 1

Findings Hansi considered but did not post.

Finding Why
Keep optional descriptions nullable in create actions Verifier: Already handled in packages/http/src/Http.php:737–747: an explicit null for an optional parameter with a non-null default is treated as omitted when its validator rejects null. This description parameter is optional, defaults to '', and uses Text(1024, 0), whose isValid(null) returns false (packages/validators/src/Text.php:94–97). Consequently the handler receives '' rather than null, so no TypeError occurs. The same configuration is used by the other create handlers. Existing HttpTest::testExplicitNullOptionalParamFallsBackToDefault covers this normalization for non-nullable typed callbacks.

Merged main (cbcb14b); no changes to this PR's code since 07e00a7 · Details · Comment @hansi-codes review to re-run, or mention @hansi-codes with a question.

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Tier A · See the inline comments. Summary


// Only the optional ones: Utopia's null-skips-validation path is reached
// through the `optional` flag.
if (!\preg_match("/->param\(\s*'description',.*,\s*true[\s,)]/U", $source)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid regex in the endpoint-discovery test

This test uses preg_match here and again at line 131 to parse endpoint source, but AGENTS.md explicitly forbids adding regular expressions. This can also silently miss declarations as their formatting changes; string-based parsing would follow the repository rule.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/unit/Platform/DescriptionParamTest.php
Line: 127

Comment:
**Avoid regex in the endpoint-discovery test**

This test uses `preg_match` here and again at line 131 to parse endpoint source, but `AGENTS.md` explicitly forbids adding regular expressions. This can also silently miss declarations as their formatting changes; string-based parsing would follow the repository rule.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

🟡 Minor · maintainability · Reply if this doesn't apply.

$runtime = $function->getAttribute('runtime');
}

$description ??= $function->getAttribute('description', '');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cover an explicit null on function update

The function update e2e case checks that omitting description preserves the saved value, but never sends description: null. Since this new nullable input is meant to preserve the value too, an explicit-null assertion here would catch regressions in this handler; the bucket test exercises a different action.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Appwrite/Platform/Modules/Functions/Http/Functions/Update.php
Line: 198

Comment:
**Cover an explicit null on function update**

The function update e2e case checks that omitting `description` preserves the saved value, but never sends `description: null`. Since this new nullable input is meant to preserve the value too, an explicit-null assertion here would catch regressions in this handler; the bucket test exercises a different action.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

🟡 Minor · testing · Reply if this doesn't apply.

@github-actions

Copy link
Copy Markdown

Security rules

No new WARNING or ERROR findings from security rules.

19 existing findings tracked in .semgrep/baseline.json
  • php.appwrite.guest-write-without-abuse-limit (12)
  • php.appwrite.secret-compare-timing (5)
  • php.appwrite.weak-secret-env-default (2)

Posted by Checks / Rules. Re-runs update this comment in place. Rule details and baseline: .semgrep/README.md.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → claude/descriptions-to-main (after).

Metric Before After Change
🚀 Requests/sec 200.15 177.46 🔴 -11.3%
⏱️ Latency P50 87.31 ms 98.39 ms 🔴 +12.7%
⏱️ Latency P95 199.31 ms 228.44 ms 🔴 +14.6%
Per-scenario breakdown & investigation details

Metrics below reflect the current branch (after). Δ P95 compares against the base.

Scenario P50 (ms) P95 (ms) Requests RPS Δ P95 (ms)
API total 98.39 228.44 11,343 177.46 +29.13
Account 181.22 336.12 597 9.98 +49.14
TablesDB 95.9 188.32 6,169 99.24 +18.5
Storage 89.03 202.87 2,985 49.55 +16.53
Functions 134.67 257.77 1,592 27.11 +31.41

Top API waits (after)

API request Max wait (ms)
tablesdb.rows.increment 497.09
account.name.update 465.43
tablesdb.rows.create 453.24
account.prefs.update 447.49
storage.buckets.create 420.65

Three independent failures, all in the test/config surface rather than the
endpoint code.

tests/unit/Platform/DescriptionParamTest.php used the doc-comment
`@dataProvider descriptionEndpoints`. PHPUnit is pinned 12.* and PHPUnit 12
reads metadata only from attributes, so the provider was never bound and the
test was invoked with no arguments:

    ArgumentCountError: Too few arguments to function
    testActionAcceptsAnExplicitNullDescription(), 0 passed ... and exactly 2 expected

Converted to #[DataProvider('descriptionEndpoints')], matching how the rest of
tests/unit/ declares providers. The provider now binds and the case runs for
all 112 discovered endpoints.

Rector (AssertComparisonToSpecificMethodRector) also flagged the subclass
guard in the same file: assertTrue($a !== $b) is now assertNotSame($b, $a),
which asserts the same thing in the form the rule requires.

tests/e2e/.../VectorsDB/DatabasesBase.php::testCreateIndexDescription was
written against Database::INDEX_HNSW_COSINE / INDEX_HNSW_DOT, which no longer
exist: main moved index types to the Utopia\Query\Schema\IndexType enum, and
the merge kept the pre-refactor constant names in the new test. That is why it
failed both at runtime (Error: Undefined constant) and under PHPStan
(classConstant.notFound). Switched to IndexType::HnswCosine->value and
IndexType::HnswDot->value, which is what the sibling index tests in this same
file already use and what the endpoint's own type whitelist accepts, and
dropped the now-unused Utopia\Database\Database import. The assertions are
untouched.

app/config/sdks/parameters.lock.json was never updated for the new param, so
Tests\Unit\SDK\ParametersTest::testMethodsAreLocked failed on the first
mismatch. Regenerated the lock from the routes themselves, using the test's own
ordering logic, and verified the result differs from the committed file in
exactly one way: "description" appended to 222 platform/method entries. No
param is reordered, renamed or removed, and no method is added or dropped, so
no released positional call shifts.

Verified locally against the pinned toolchain: phpunit on both affected unit
files is green (114 tests, 10599 assertions), rector --dry-run is clean, and
pint --test passes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@hansi-codes hansi-codes Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Tier A · Looks good to merge. Summary

HarshMN2345 and others added 3 commits October 16, 2026 18:22
…resh the SDK lock

Drops the explicit-null handling I had added on top of #14355. That 500 is not
specific to description: 211 optional Text params across main's create endpoints
share the shape (entrypoint and commands on Functions/Create.php, for two),
because Utopia skips validation for an explicit null and only falls back to the
declared default when the key is absent. Fixing it for description alone would
be inconsistent with the rest of the API, so it belongs in its own PR.

What remains on top of #14355 is only what main requires:

- tests/e2e/.../VectorsDB/DatabasesBase.php and the two validator unit tests
  used Database::INDEX_HNSW_* and the pre-enum attribute constants; main has
  moved to the IndexType/ColumnType enums, so they died resolving a constant
  before reaching their assertions.
- app/config/sdks/parameters.lock.json carried no description entries, so
  ParametersTest::testMethodsAreLocked failed on every touched method.
  Regenerated, not hand-patched: 222 entries gain "description", no method
  added, removed or reordered.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…o-main

# Conflicts:
#	tests/e2e/Services/Project/KeysBase.php
@HarshMN2345
HarshMN2345 merged commit 561bd47 into main Oct 16, 2026
7 checks passed
@ChiragAgg5k ChiragAgg5k mentioned this pull request Oct 21, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants