8 min

Source-exported projects need a portability test

Source-exported projects may still depend on their AI builder. Test runtime calls, SDKs, identity, data, CI, and hosting before you sign.

Source-exported projects need a portability test

Exporting source code proves that you received files. It does not prove that the project can build, start, authenticate users, read production data, or deploy after the original AI app builder disappears. Treat portability as an acceptance test, not as a checkbox in a sales contract.

I have inherited enough generated applications to distrust a clean repository on sight. The expensive failures usually hide outside the obvious application code: a runtime request to a vendor service, an authentication callback registered in someone else's tenant, a database policy that never entered version control, or a deployment setting that exists only in a managed dashboard. A project is portable only when your team can reproduce its working behavior from the export and documented external services under accounts you control.

Source-exported projects can still depend on the builder

A source-exported project runs independently only if every required build-time and runtime dependency is available, documented, transferable, and licensed for use outside the builder. That definition is stricter than "the repository compiles." It covers the path from a blank machine to a working production release, including identity, data, scheduled work, secrets, network rules, and recovery.

Three different claims often get blurred. Source access means you can inspect files. Build independence means you can produce artifacts without calling the builder. Runtime independence means those artifacts keep serving real requests without the builder. A vendor can satisfy the first claim while failing the other two.

The distinction has a direct contract consequence. If the contract promises "source export," you may receive a React directory, a package manifest, and a README while still needing a proprietary SDK or hosted gateway. Ask for an operational outcome instead: an authorized engineer must be able to build and run the accepted release in a clean environment using accounts owned by the customer.

Define the boundary before testing. Managed services are not automatically a portability failure. Most serious applications depend on a cloud, payment processor, email provider, or identity service. The issue is whether you chose those dependencies knowingly and can move or replace them under your own agreement. A hidden vendor service that cannot be contracted separately is different from a documented PostgreSQL database in your cloud account.

Create a dependency register with four fields for every external component: owner, purpose, replacement path, and failure behavior. "Owner" means the legal account holder, not the person who knows the password. "Replacement path" may be a migration procedure, an interface you can reimplement, or an explicit decision to keep the service. "Failure behavior" records what users see when it is unavailable. If the seller cannot fill in those fields, the export has not been explained well enough to price its risk.

The best first test is mundane: disconnect access to the builder account and try the application. Revoke its tokens in a staging copy, block its known domains at the network boundary, and watch what fails. Do not begin by reading every file. Runtime evidence finds dependencies that code review misses, including injected configuration and calls made by compiled packages.

Trace the application while real workflows run

Runtime callbacks reveal themselves when you observe DNS, outbound connections, browser requests, and background jobs during representative workflows. A home page that loads proves little. Exercise sign-in, password recovery, file upload, search, billing transitions, email delivery, scheduled tasks, administrative actions, and any AI-backed feature the product actually sells.

Run the application in a fresh staging network where outbound traffic is logged. Give it only the destinations listed in the dependency register. Start with a deny policy for unlisted traffic if your environment permits one. Every blocked request becomes a question: Is it required, optional telemetry, an update check, or an undocumented control-plane call?

Browser developer tools matter because some dependencies never touch your server. Inspect the Network panel after clearing storage and using a new session. Look at request hosts, failed preflight requests, WebSocket connections, loaded scripts, and redirects. A frontend may call a builder API directly even when the server repository looks self-contained. Service workers can also preserve old behavior, so unregister them before repeating the test.

On a Unix-like source tree, this search gives a useful first inventory:

grep -R -n -E 'https?:|wss?:|fetch[(]|axios|WebSocket|grpc|callback|webhook' .

Expect output shaped like path/to/file:line:matching text. Review generated lockfiles separately from application code, because a domain in package metadata does not prove a runtime call. Conversely, a clean search does not prove independence: environment variables can assemble hosts, DNS aliases can hide them, and binary dependencies can make their own requests.

Search for vendor terms, SDK imports, and environment-variable prefixes as separate passes. Then inspect lockfiles to see whether packages resolve from a public registry or a private vendor registry. Cache success can mislead you here. Delete language package caches in the isolated test environment and rebuild with only the documented registry credentials.

Trace background behavior long enough to cross a scheduler boundary. A web process may look healthy while queue consumers fail, scheduled reports stop, and webhook retries pile up. Trigger jobs manually when waiting for their normal schedule would slow the test. Record the destination, request method, authentication type, response class, retry rule, and user-visible consequence for each outbound integration.

Do not accept "that callback is only telemetry" without testing its failure. Block it and repeat the workflow. Optional telemetry should time out quickly or fail without changing the user's operation. I have seen logging calls sit inside a request transaction and turn a harmless analytics outage into a failed save. The label does not determine the risk; the code path does.

Proprietary SDKs need a removal or licensing path

A proprietary SDK is acceptable only when you can obtain it, build against it, run it legally, and replace it on a schedule the business can tolerate. Having its wrapper source in the export does not grant rights to the SDK, protocol, hosted endpoint, or model behind it.

Inventory dependencies from both manifests and source imports. For JavaScript, inspect package.json plus its lockfile. For Go, inspect go.mod and checksums. For Flutter, inspect pubspec.yaml and its lockfile. Note packages fetched from Git repositories, private registries, local paths, or archives. Those are common places for builder-owned components to hide.

For each questionable package, answer four concrete questions:

  1. Can a new customer-owned build agent download the exact version?
  2. Does the license permit production use after the builder contract ends?
  3. Does the package call a service that the customer can contract for directly?
  4. Is the interface small enough to replace, and is that interface tested?

Do a cold build with credentials created in a customer-owned organization. Do not copy a developer's entire configuration directory into the test machine. That imports cached packages, implicit registry settings, and personal tokens, which defeats the exercise. A correct build procedure starts with the documented toolchain version and declares each extra credential individually.

Generate a software bill of materials if the toolchain supports it, but do not confuse that document with a portability verdict. An SBOM lists components; it rarely tells you who controls a remote account or whether a package phones home. Use it to reconcile what the repository declares against what the built artifact contains.

Where a proprietary client sits behind a narrow adapter, write a contract test against the adapter now. Feed it a known request, assert the normalized response, and run the same test with the network endpoint blocked. The failure should be explicit and bounded. If proprietary calls appear throughout view components, route handlers, and data models, price a refactor before signing. The problem grows with call-site count and semantic coupling, not with the SDK's line count.

Teams often recommend replacing every proprietary dependency before purchase. That sounds safe, but it can waste weeks on services the buyer intends to retain. The better rule is to remove dependencies that are unavailable or uncontractable, isolate the ones you accept, and attach migration cost to the rest. Portability is control over choices, not an application with zero external services.

Authentication belongs to more than the source tree

Authentication moves cleanly only when the customer controls the identity tenant, redirect registrations, signing keys, user identifiers, email templates, and recovery process. Application code usually captures just one slice of that system.

Start by drawing the login path as actual hops. A browser reaches the application, the application redirects to an identity provider, the provider returns to a registered callback, and the backend exchanges or validates credentials. Record the owner and configuration location at each hop. If any console can only be accessed through the builder's organization, require transfer or replacement before acceptance.

Managed authentication creates a particularly awkward data problem. The application's user table may store a provider-specific subject rather than an email address or an internal durable ID. Exporting rows does not help if a new identity tenant issues different subjects. Test account matching, duplicate handling, password users, social-login users, multifactor enrollment, locked accounts, and users with changed email addresses.

OpenID Connect defines the sub claim as a locally unique, never reassigned identifier within the issuer's scope. The issuer matters. Treating sub alone as globally portable can attach the wrong application record after a tenant change. Store and compare the issuer with the subject, then design an explicit mapping for migration.

Your test needs at least four accounts: a normal user, an administrator, a disabled user, and a user with a second authentication factor. Move or recreate the identity configuration in a customer-owned tenant, restore a staging database copy, and verify successful login plus denied access. Also test logout, token refresh, password reset, invitation acceptance, and session expiry. Teams remember the happy login path and discover broken recovery only after cutover.

Search the repository for redirect URIs, client IDs, issuer names, cookie domains, audience values, and signing-key references. Keep secrets out of the repository, but keep their names, owners, creation steps, rotation steps, and required formats in deployment documentation. A sample environment file should identify the contract without containing live values:

AUTH_ISSUER=
AUTH_CLIENT_ID=
AUTH_CLIENT_SECRET=
AUTH_CALLBACK_ORIGIN=
SESSION_SIGNING_KEY=

Do not accept a shared builder tenant as a permanent arrangement merely because migration can happen "later." Identity migrations touch every active user and every authorization assumption. Either transfer control before signing or make the replacement a priced, tested condition of the deal.

Database portability includes behavior and operations

Keep deployment beside the build
Build through chat, then use Koder.ai deployment and hosting while you prepare an independent runtime test.

A database dump is insufficient when schemas, extensions, row-level policies, triggers, object storage, queues, backups, and connection rules live outside it. Database portability means you can restore the data and reproduce the behavior that protects and changes it.

Begin with an empty customer-owned PostgreSQL instance at the documented major version. Apply repository migrations in order. If the project has no migrations and requires importing a vendor-created schema dump, record that as a defect. A dump may capture today's state, but it does not explain how the next release changes that state safely.

Compare the restored schema with production or staging. Check tables, columns, types, constraints, indexes, sequences, views, functions, triggers, enabled extensions, roles, grants, and row-level security policies. Many migration tools omit roles and provider-level settings. An application can pass basic read tests while administrative jobs fail because the restored role lacks permission on a sequence or function.

Then verify the data path with a controlled round trip:

  1. Create a record through the public application workflow.
  2. Read it through a second authorized user where sharing is expected.
  3. Confirm an unauthorized user cannot read or change it.
  4. Update and delete it through the application.
  5. Restore the database into another clean instance and repeat the reads.

This sequence tests application code, authorization policy, generated values, and recoverability together. Direct SQL row counts cannot cover those behaviors.

Treat object storage as part of the database boundary when rows point to uploaded files. Export buckets, object metadata, access rules, lifecycle rules, and URL-generation settings. A restored database full of object keys is useless when the underlying files remain in a builder-owned bucket. The same warning applies to search indexes and vector stores: decide whether to migrate them or rebuild them, and prove the rebuild procedure.

Measure neither success nor failure from a single small dump. Use a staging-sized copy that contains long text, nulls, non-ASCII characters, large objects, timestamps around daylight-saving changes, and representative relationships. You do not need invented benchmarks. You need evidence that the transfer completes within your allowed outage and that the application behaves after it.

Backup claims require a restore. Identify who schedules backups, where copies live, who can decrypt them, how retention works, and how you detect a failed backup. Restore one into an isolated account with written instructions. If only the builder can press the restore button, you have a service feature, not an independent recovery plan.

A missing CI pipeline is missing product knowledge

Host under your own domain
Koder.ai supports custom domains with its deployment and hosting, keeping the public address tied to your project.

An exported repository without reproducible continuous integration leaves the buyer to rediscover tool versions, build order, tests, artifact packaging, database migration timing, and release gates. That knowledge is part of the deliverable even when the seller's internal pipeline cannot be transferred verbatim.

Look for pipeline definitions, container build files, tool-version files, test commands, lint rules, migration commands, and infrastructure definitions. Then compare them with a real deployment log. Documentation often describes a simple web build while the managed platform quietly generates configuration, injects a server component, builds a mobile bundle, or runs database migrations.

Reconstruct the minimum pipeline in a customer-owned CI account. It should check out a pinned revision, install a declared toolchain, fetch dependencies, run tests, produce immutable artifacts, and record artifact identity. Deployment may remain manual during the test, but the artifact that reaches staging must be the artifact the pipeline produced.

A compact acceptance log can use this shape:

revision: 4f2c9ab
toolchain: declared versions loaded
dependencies: cold install passed
tests: unit and integration passed
artifacts: web, server, mobile
migrations: dry run passed
staging: health and workflow checks passed

The values will differ, but every line needs machine output or a linked internal record, not a person's recollection. Keep the log with the acceptance evidence.

Do not demand the seller's secret deployment machinery if you do not need it. Demand enough instructions and configuration to reproduce the result. A portable pipeline can target a different CI product as long as it performs the same required stages and does not weaken release controls.

Mobile applications add signing assets, package identifiers, store accounts, and push-notification credentials. Those are easy to overlook because a source build can run in an emulator without them. Verify customer ownership of distribution accounts and document certificate rotation. For server and web applications, include domain verification, TLS certificate issuance, DNS changes, and cache invalidation in the release exercise.

The pipeline test ends with a change, not with rebuilding the supplied commit. Make a harmless visible edit, add a database migration that can be rolled back, build it, deploy it to staging, verify it, and execute the rollback. This catches generated artifacts that were checked in once but cannot be regenerated.

Pin the operating-system packages used by the build as well as the language toolchain. Native modules may compile against libraries that happen to exist on the builder's image. A new runner then fails before application tests start, or worse, produces an artifact with different behavior. Capture package names and versions in a container definition or an equivalent machine-readable build description.

Keep secrets out of CI logs while proving that the pipeline can obtain them from a customer-controlled store. The test should create a short-lived staging credential, inject it by the documented mechanism, and rotate it without editing source. If a secret must be pasted into a vendor dashboard by support staff, record that dependency instead of hiding it inside setup notes.

Hosting assumptions surface during a clean-room deployment

A clean-room deployment proves portability when a team unfamiliar with the builder can launch the system in a customer-owned environment using only the export, declared services, and written instructions. Run it before contract acceptance, with a time box and an issue log.

Choose an environment that matches the intended operating model. Moving from a managed platform to raw virtual machines creates unrelated work and can make a portable project look broken. Match required primitives such as containers, PostgreSQL, object storage, scheduled jobs, secrets, and load balancing, but do not recreate undocumented vendor magic.

Inspect the application for assumptions about writable local disks, fixed ports, sticky sessions, trusted proxy headers, region names, injected hostnames, and platform-specific environment variables. The Twelve-Factor App recommends storing configuration in the environment and treating backing services as attached resources. Those ideas remain useful, but environment variables alone do not document ownership, formats, or creation. Pair each variable with an operational record.

Health checks deserve direct testing. A process that returns success before migrations finish or before required dependencies connect can enter a restart loop behind an orchestrator. Separate liveness from readiness where the hosting system supports it. Stop the database, object store, and queue one at a time, then observe status codes, logs, retry behavior, and recovery after the service returns.

Confirm how the application handles multiple instances. In-memory sessions, local upload directories, and process-local job locks work on one managed instance and fail after scaling. Start two instances, send the same user's requests through both, and run concurrent job workers. Check that sessions persist, files remain available, and a scheduled task does not execute twice unless it is designed to be idempotent.

Observe shutdown as carefully as startup. Send a termination signal while requests and background jobs are active. The process should stop accepting new work, finish or safely return claimed jobs, close connections, and exit within the host's grace period. A managed builder may have concealed abrupt shutdowns with long timeouts or retries that your new host does not share.

Logs and metrics also carry hosting assumptions. Confirm that the application writes structured events to a documented destination, removes secrets and personal data where required, and exposes enough information to diagnose a failed workflow. A proprietary dashboard is optional only when standard output or another customer-controlled sink preserves the necessary evidence.

Region and data-location claims need configuration evidence. Record where the application, database, backups, logs, and object storage run, plus which external services receive data. A region selector for the web process does not keep data in country if authentication or analytics sends it elsewhere. The contract should name who approves changes to those locations.

Koder.ai supports source export, deployment and hosting, custom domains, snapshots, and rollback. If you evaluate an exported Koder.ai project for independent operation, use the same clean-room standard: test the exported React, Go with PostgreSQL, or Flutter components in the environment you intend to own, and document any service you choose to retain.

Put pass and fail conditions into the contract

Generate a Go backend
Describe the server behavior, let Koder.ai build with Go and PostgreSQL, then examine the exported dependencies.

The contract should define portability as observed behavior, list the acceptance environment, assign remediation responsibility, and preserve enough time to fix failures before final payment or lock-in. Vague ownership language will not rescue an application that nobody else can deploy.

Attach an acceptance matrix rather than relying on a paragraph titled "source code." Each row should name a capability, test procedure, expected result, evidence, responsible party, and severity. Cover cold build, runtime network calls, identity transfer, database restore, file storage, background work, CI, clean deployment, monitoring, backup restore, a small change, and rollback.

Use pass criteria that a third party can observe. "No critical proprietary dependency" invites argument. "The staging application completes workflows A through F while all builder-owned credentials are revoked and builder domains are blocked" can be tested. Define allowed dependencies by name and account owner so the team does not mistake an approved managed service for a failure.

Require delivery of source and operational materials at a pinned revision: lockfiles, migrations, build definitions, infrastructure configuration where available, environment-variable catalog, dependency register, data export, identity migration plan, runbooks, license notices, and signing or distribution assets that belong to the customer. Record exclusions explicitly. Silence should not mean acceptance.

Set severity by business effect. A missing optional analytics event is not equal to a login outage. A useful scheme distinguishes blockers that prevent build or core workflows, major defects that remove an important capability or recovery path, and minor defects with a documented workaround. Tie acceptance and remediation dates to those levels without inventing a universal timetable.

Define the test data and test operator too. Sellers sometimes demonstrate portability with an empty database and an administrator account that bypasses ordinary authorization. Require representative users, roles, files, and background jobs, with customer staff performing the documented procedure. Keep secrets synthetic, but keep the relationships and edge cases realistic.

Costs belong in the evidence packet. Record the separately billed services required to run the exported release and any minimum tier, data-egress charge, or private registry subscription the seller identifies. The test need not forecast every future bill. It must prevent a supposedly independent export from revealing an unavoidable vendor contract only after signature.

Include cooperation duties for services that cannot transfer instantly. The seller may need to rotate keys, approve an identity export, move a domain, or provide a final data snapshot. Name the action and the person responsible. "Reasonable assistance" is hard to enforce when production is down.

Preserve the right to repeat tests after remediation and after the final export. Generated projects change quickly, and a fix proven against last month's revision says nothing about new dependencies added yesterday. Pin the tested commit and artifact hashes in the acceptance record.

Do not let an escrow clause substitute for this work. Escrow can deliver files after a trigger event, but files without current build instructions, credentials ownership, and tested recovery paths may arrive too late to help. Operational independence must exist while both parties can still cooperate.

Sign when a second team can build, run, change, deploy, and recover the accepted release without privileged help from the original builder. Anything less is source possession with an unresolved migration project attached, and the contract price should reflect that work.

FAQ

Can exported source code run without the AI app builder?

Sometimes, but the repository alone cannot prove it. Run a cold build and a clean deployment with builder credentials revoked, then exercise real workflows while logging outbound traffic.

What is the difference between source access and runtime independence?

Source access lets you inspect and modify files. Runtime independence means the working application can serve users without required calls, credentials, or infrastructure controlled only by the original builder.

How do I find hidden callbacks to an app builder?

Search source and manifests for domains, SDKs, callbacks, WebSockets, and environment variables, then observe browser and server traffic in staging. Blocking unlisted destinations is more reliable than trusting names such as telemetry or analytics.

Does using managed authentication prevent portability?

No, if your organization controls the identity tenant and can migrate users, redirect registrations, signing keys, and recovery flows. A shared builder tenant without a tested transfer path is a serious dependency.

Is a PostgreSQL dump enough to move the database?

Usually not. You also need migrations, roles, grants, extensions, policies, triggers, object files, backup procedures, and proof that authorized and unauthorized workflows still behave correctly after restore.

What should a source export include besides application files?

It should include lockfiles, migrations, build definitions, an environment-variable catalog, dependency and license records, identity and data migration plans, and operational runbooks. Mobile projects also need customer-controlled signing and distribution assets.

Can I test portability before buying the project?

You should make it part of acceptance. Use a clean customer-owned environment, revoke builder access, build a pinned revision, deploy it, change it, restore its data, and test rollback.

Are proprietary SDKs always a deal breaker?

No. They are acceptable when you can obtain and license them independently, contract for any required service, isolate their interface, and afford the replacement plan.

Why does the exported project need CI configuration?

CI captures the reproducible path from a revision to tested artifacts. Without it, tool versions, build order, generated files, migration timing, and release checks remain undocumented product knowledge.

What contract wording proves an export is portable?

Define observable tests and expected results instead of promising only source delivery. Require core workflows to pass in a customer-owned environment while builder credentials are revoked and builder destinations are blocked.

Related posts