chore: absorb telemetry, system, psr7 and smtp into packages/ by loks0n · Pull Request #13721 · appwrite/appwrite · GitHub
Skip to content

chore: absorb telemetry, system, psr7 and smtp into packages/ - #13721

Closed
loks0n wants to merge 195 commits into
mainfrom
feat/absorb-leaves-1
Closed

loks0n wants to merge 195 commits into
mainfrom
feat/absorb-leaves-1

Conversation

@loks0n

@loks0n loks0n commented Sep 16, 2026

Copy link
Copy Markdown
Member

Summary

Phase 2 batch, four dependency-free leaves, each imported from its mirror with history (bin/monorepo absorb, one subtree merge plus a plumbing commit per package) and reshaped to the standard layout (RFC step A, non-breaking):

telemetry system psr7 smtp
Sources src/Telemetry flattened to src/ src/System flattened src/Psr7 flattened already src/
Test namespace Tests\\Telemetry → Utopia\\Telemetry\\Tests Utopia\\Tests → Utopia\\System\\Tests Utopia\\Tests\\Psr7 → Utopia\\Psr7\\Tests …\\Tests\\Unit → …\\Tests
E2E tier OTLP transport tests (loopback Swoole server) in tests/E2E none none Mailpit compose, unchanged
PHPStan own level max new, level 5 own level 10 own level max

No baselines were needed. Rector configs kept where the mirror had one, made standalone (they used to require the old monorepo's root config, which exists nowhere any more) and with phpunitCodeQuality dropped because it needs a package-local installed.json; smtp's rectorPreset also dropped, since it annotated source classes with their test class names.

Two things this batch settles for every later package

  • replace at scale. Between them these four are required by 14 vendored packages (telemetry by nine). With the root replace-ing them, the lock drops all four and nothing else moves; the dependants resolve from packages/. psr7 and smtp were never in the root require at all, only transitive, and replace covers that too.
  • Hoisting is enforced. Because replace hides a package's own require from the solver, its third-party dependencies must be declared by the root or they vanish from the lock. Six were hoisted here (nyholm/psr7, open-telemetry/exporter-otlp, open-telemetry/sdk, symfony/http-client, psr/http-factory, psr/http-message), and bin/monorepo validate now fails when a package requirement is missing from the root.

Telemetry drift, checked

Appwrite ran 0.4.10; the mirror head is one merge past the 0.4.11 tag. Since 0.4.8 the only public-surface change is an added exporter wrapper class, nothing removed or re-signed, so the nine dependants are unaffected.

Known local-only failure

bin/monorepo test telemetry's e2e tier segfaults on macOS (Swoole 6 + PHP 8.5) in one retry-timing test. Reproduced on the untouched import commit, so not introduced here; the unit tier passes. Let the Linux runner decide.

Merging

Merge with a merge commit, not a squash: the four subtree annotations are what the split continues from.

Verification

  • bin/monorepo validate: all packages valid; the new hoisting rule fires when a hoisted line is removed
  • bin/monorepo check clean for all four; test green for system (33), psr7 (47), smtp (28 unit + 28 e2e); telemetry unit 24 green
  • vendor/bin/phpunit --testsuite packages: 450 tests, 4 skipped
  • Root PHPStan clean on every Appwrite consumer of the four namespaces; composer validate valid; dump-autoload without PSR-4 warnings
  • Root unit suite: only the known host-environment failures

🤖 Generated with Claude Code

ChiragAgg5k and others added 20 commits August 26, 2026 23:29
…ion-suggest

fix(telemetry): make ext-protobuf a suggestion, not a requirement
chore: stop committing package lock files
chore: stop committing package lock files
chore: stop committing package lock files
chore: stop committing package lock files
feat(system): add cgroup-aware memory capacity method
…trics

fix(telemetry): omit empty metrics from OTLP exports
…ad-pooled-connection

fix(telemetry): retry an export once when the pooled connection is reset mid-request
…stale-session

fix(smtp): let a holder reuse a connection the server may have closed
perf(telemetry, circuit-breaker): record less per call on the cache path
…57a97b3704'

git-subtree-dir: packages/telemetry
git-subtree-mainline: d5b1aad
git-subtree-split: 852e76c
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…1d40047'

git-subtree-dir: packages/system
git-subtree-mainline: 45af8bb
git-subtree-split: f707764
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…f899d'

git-subtree-dir: packages/psr7
git-subtree-mainline: 04ea3aa
git-subtree-split: cf70bec
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d68d6'

git-subtree-dir: packages/smtp
git-subtree-mainline: ca004cd
git-subtree-split: 7115e54
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…the root

The root replaces every absorbed package, which hides the package's own require block from the solver: a third-party dependency a package declares only resolves when the root declares it too. validate now fails for any non-php, non-ext, non-utopia-php requirement missing from the root require, and the RFC says so.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Step A of rfc/monorepo.md for the four leaves imported in the preceding absorb commits: sources flattened to src/, test namespaces renamed to Utopia\<Ns>\Tests\, service-bound tests under tests/E2E, standalone phpstan.neon, Appwrite's Pint style applied. The root drops utopia-php/telemetry and utopia-php/system from require (psr7 and smtp were only transitive) and replaces all four; their third-party requirements are hoisted into the root require: nyholm/psr7, open-telemetry/exporter-otlp, open-telemetry/sdk, symfony/http-client (telemetry), psr/http-factory, psr/http-message (psr7). The lock loses the four packages and nothing else moves.

telemetry: src/Telemetry -> src; tests/Telemetry -> tests, Tests\Telemetry -> Utopia\Telemetry\Tests; TransportIntegrationTest and MockOtlpServer (bind a Swoole OTLP server on loopback) -> tests/E2E with a test:e2e script, no compose file. PHPStan level max, no baseline. rector.php made standalone (it required the old monorepo's ../../rector.php, which exists neither here nor on the mirror) and the PHPUnit set dropped (its rules are bonded to vendor/composer/installed.json, which a package has none of); Rector changed one file.

system: src/System/System.php -> src/System.php; tests/System -> tests, Utopia\Tests -> Utopia\System\Tests; testGetEnv sets its own env instead of relying on phpunit.xml so the root packages suite can run it. New phpstan.neon at level 5 over src and tests, no baseline. No rector.php, none before.

psr7: src/Psr7 -> src; tests/Psr7 -> tests, Utopia\Tests\Psr7 -> Utopia\Psr7\Tests. phpstan.neon standalone at its level 10 over src and tests, no baseline. rector.php made standalone as above; Rector changed nothing.

smtp: tests/Unit -> tests, Utopia\SMTP\Tests\Unit -> Utopia\SMTP\Tests; tests/E2E and the Mailpit compose file unchanged. phpstan.neon standalone at level max over src and tests, no baseline. rector.php made standalone as above; Rector added @see test annotations to ten classes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@loks0n loks0n self-assigned this Sep 16, 2026
@greptile-apps

greptile-apps Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

The package absorption appears behaviorally mergeable, but the explicit repository testing requirement must be satisfied before merging.

Fix All in Claude CodeFindings

  1. P2 Tests Mirror Source Literals ▶
  2. P2 Test Does Not Parse Endpoint ▶
Fix with agent prompt
### Issue 1
packages/psr7/tests/ConstantsTest.php:16-24
These assertions duplicate every method constant's literal value instead of testing behavior that uses the constants. They therefore provide no behavioral signal and fail only when the implementation and its mirror drift apart. The same pattern appears in `Request/FactoryTest.php`, which pins the private `utopia-` boundary prefix and concrete `MultipartBody` class rather than validating only the emitted multipart contract. This violates the repository directive not to mirror source code or configuration in assertions and must be corrected before merging.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

### Issue 2
packages/telemetry/tests/Adapter/OpenTelemetry/Swoole/TransportTest.php:47-51
This test constructs an endpoint but checks only the unrelated `contentType()` getter. Broken host, port, path, query, or TLS parsing would leave it green. The custom-header, timeout, pool-size, socket-buffer, query-string, and default-port tests repeat this no-op pattern. This violates the repository directive to test observable behavior rather than mirror configuration and must be corrected before merging; these cases should observe actual requests or connections.

---

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

Summary

This PR absorbs the PSR-7, SMTP, system, and telemetry libraries into the monorepo as independently structured packages.

  • Redirects root autoloading to packages/ and replaces the corresponding Composer packages.
  • Hoists package dependencies into the root manifest and extends monorepo validation to enforce hoisting.
  • Imports package source, tests, standalone analysis configuration, documentation, and mirror workflows.
  • Introduces test suites containing repository-rule violations: several assertions mirror literals or check values unrelated to the behavior named by the test.

Reviews (1) · Last reviewed commit: "refactor: load telemetry, system, psr7 a..."

Comment on lines +16 to +24
$this->assertSame('GET', Method::GET);
$this->assertSame('POST', Method::POST);
$this->assertSame('PUT', Method::PUT);
$this->assertSame('PATCH', Method::PATCH);
$this->assertSame('DELETE', Method::DELETE);
$this->assertSame('HEAD', Method::HEAD);
$this->assertSame('OPTIONS', Method::OPTIONS);
$this->assertSame('CONNECT', Method::CONNECT);
$this->assertSame('TRACE', Method::TRACE);

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.

P2 Tests mirror source literals

These assertions duplicate every method constant's literal value instead of testing behavior that uses the constants. They therefore provide no behavioral signal and fail only when the implementation and its mirror drift apart. The same pattern appears in Request/FactoryTest.php, which pins the private utopia- boundary prefix and concrete MultipartBody class rather than validating only the emitted multipart contract. This violates the repository directive not to mirror source code or configuration in assertions and must be corrected before merging.

Context Used: Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/psr7/tests/ConstantsTest.php
Line: 16-24

Comment:
**Tests mirror source literals**

These assertions duplicate every method constant's literal value instead of testing behavior that uses the constants. They therefore provide no behavioral signal and fail only when the implementation and its mirror drift apart. The same pattern appears in `Request/FactoryTest.php`, which pins the private `utopia-` boundary prefix and concrete `MultipartBody` class rather than validating only the emitted multipart contract. This violates the repository directive not to mirror source code or configuration in assertions and must be corrected before merging.

**Context Used:** Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))

---

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

These tests are imported from the library unchanged; an absorb moves a package without rewriting it, so its mirror history stays a pure relocation. Test quality in psr7 and telemetry is library work and belongs in its own change against packages/psr7 and packages/telemetry, where it also releases through bin/monorepo release.

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.

That context is fair. An absorb commit should preserve the imported package history and remain a pure relocation; rewriting its tests would mix package-quality work into the migration. I agree this is not an actionable finding for PR #13721. The assertion-quality concerns belong in a follow-up change against packages/psr7 (and packages/telemetry where applicable), with its own release. I’m withdrawing this as a merge blocker for the absorb.

Comment on lines +47 to +51
public function testConstructorParsesEndpointCorrectly(): void
{
$transport = new Swoole('https://otel.example.com:4318/v1/metrics?foo=bar');

$this->assertSame(ContentTypes::PROTOBUF, $transport->contentType());

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.

P2 Test does not parse endpoint

This test constructs an endpoint but checks only the unrelated contentType() getter. Broken host, port, path, query, or TLS parsing would leave it green. The custom-header, timeout, pool-size, socket-buffer, query-string, and default-port tests repeat this no-op pattern. This violates the repository directive to test observable behavior rather than mirror configuration and must be corrected before merging; these cases should observe actual requests or connections.

Context Used: Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/telemetry/tests/Adapter/OpenTelemetry/Swoole/TransportTest.php
Line: 47-51

Comment:
**Test does not parse endpoint**

This test constructs an endpoint but checks only the unrelated `contentType()` getter. Broken host, port, path, query, or TLS parsing would leave it green. The custom-header, timeout, pool-size, socket-buffer, query-string, and default-port tests repeat this no-op pattern. This violates the repository directive to test observable behavior rather than mirror configuration and must be corrected before merging; these cases should observe actual requests or connections.

**Context Used:** Call out and harshly judge implementation-coupled tests. We don't mirror source code, configuration, or version pins in assertions. We test observable behavior; use linters for syntax and schema checks. ([source](https://app.greptile.com/review/custom-context?memory=instruction-0))

---

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

Fix in Claude Code Fix in Codex

@github-actions

Copy link
Copy Markdown

✨ Benchmark results

Comparing main (before) → feat/absorb-leaves-1 (after).

Metric Before After Change
🚀 Requests/sec 231.91 232.84 ⚪ +0.4%
⏱️ Latency P50 75.6 ms 75.84 ms ⚪ +0.3%
⏱️ Latency P95 173.21 ms 170.67 ms ⚪ -1.5%
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 75.84 170.67 14,706 232.84 -2.54
Account 133.74 257.8 774 12.9 +2.32
TablesDB 72.89 134.82 7,998 129.67 +1.38
Storage 71.05 156.09 3,870 64.15 -1.1
Functions 105.41 206.95 2,064 34.85 -4.77

Top API waits (after)

API request Max wait (ms)
functions.delete 415.45
account.name.update 397.39
functions.create 374.16
account.prefs.update 352.92
functions.variables.update 321.59

@loks0n

loks0n commented Sep 16, 2026

Copy link
Copy Markdown
Member Author

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.