C# business logic: the Net Operation Project
The Net Operation Project is the C# authoring surface for one Moltaro installation. The workspace owns a tree of C# source files; Moltaro compiles that source against a generated typed schema contract built from the current entity configuration, using the Moltaro .NET SDK programming model. You write operational logic — functions, services, integrations — while the platform keeps ownership of the schema, the project files, and the build toolchain. Its frontend counterpart is the Workspace UI Project, which publishes trusted custom pages built from workspace-owned Vue source.
The project consumes the generated Entity contract; it does not own Entity
Manual Order configuration, protected rank storage, or positional Move APIs.
Those remain governed Moltaro application behavior rather than workspace C#
schema or business-logic surface. If Manual Order is active, inserting an entity
through the generated context’s normal SaveChanges pipeline automatically
allocates its canonical tail position in the same transaction. Workspace code
must not calculate or submit a platform Manual Order rank.
In an explicit caller transaction, include every create, archive, restore, or
delete for an ordered Entity in the first Entity SaveChanges. A later save
cannot safely introduce the Manual Order lock after an Entity mutation lock has
already been acquired. It fails before lock acquisition with
MoltaroPreCommitSaveRejectedException and code
moltaro.preCommit.manualOrderAfterEntityLockUnsupported. Inspect the typed
error and either stage the complete unit in the first save or retry the
lifecycle operation in a new transaction; never parse exception text.
The SDK’s policy-free LexicographicRankKeyGenerator may be used for a custom
workspace-owned ordering algorithm. It generates standalone ordinal keys only;
it neither reads nor changes the platform-owned Manual Order position.
Project source can contain every function shape Moltaro supports: entity validation, mutation, and trigger functions, global functions and actions, commands and API-enqueued jobs, inbound HTTP endpoints, and functions bound to CRON schedules. There is no separate outbound-webhook feature: outbound HTTP calls are ordinary C# code inside trigger or global functions.
API-first authoring and optional editors
Section titled “API-first authoring and optional editors”API-first authoring targets the API host of one configured workspace. Resolve
every /api/workspace/... route below against that installation’s
WORKSPACE_API_BASE_URL, never against moltaro.com. The
workspace API connection guide
explains the human bootstrap, service key, and downloaded agent guide.
Authoring lives in the Constructor area under the Automation & logic group: the Development page (titled “Business Logic Development”) hosts both editing modes, next to the Function Catalog and Function Schedules pages.
- Configuration API — the primary path for AI agents and automation: templates, unsaved-buffer Roslyn assistance, immutable revisions, checks, builds, and polling are all public operations. Start with the AI agent development quickstart.
- Studio — in-browser editing over the stored source tree: a code editor with server-side Roslyn diagnostics, completions, hover, and signature help; source templates for common shapes; navigation over a source index; and save, save-and-check, and save-and-build actions.
- NET Project — an optional human/local-IDE workflow: download a generated, ready-to-build solution ZIP, edit locally, and upload the result.
Both modes read and write the same versioned file tree stored in the
workspace database. ZIP files are transport only: Moltaro generates the
.sln, .csproj, props, and assembly references on every download, and on
upload it imports only allowed source files (src/**/*.cs, Markdown docs)
plus external NuGet PackageReference entries, ignoring generated project
files and build outputs.
Immutable revisions
Section titled “Immutable revisions”Source history is a sequence of immutable revisions. A Studio save or a ZIP upload never edits existing source — it creates a new revision and makes it the working revision, while the current revision and the active compiled artifact stay unchanged until a build succeeds. Draft, validated-draft, or failed revisions that never produced an artifact can be deleted; published revisions are retained for attribution.
The build pipeline
Section titled “The build pipeline”Builds run in the background and follow one explicit pipeline:
- Generate the schema contract from the current entity configuration.
- Compile the working revision against it, storing full diagnostics.
- Discover function descriptors from the compiled assembly.
- Synchronize the function catalog — new functions appear, removed functions are retired and blocked from new invocations.
- Activate the new artifact. Exactly one artifact is active at a time.
A failed build never replaces the active artifact: the previous logic keeps running until a new build succeeds. A check uses the same compile path and diagnostics but activates nothing — it only validates the working revision.
Check after schema changes
Section titled “Check after schema changes”Schema changes do not trigger recompilation. Additive changes (new entities, new fields) are safe: the active artifact keeps running and the next build sees the new contract. Destructive or type-changing edits mark the project as needing validation while the active artifact continues to run; the Development page then offers an explicit Check project action that compiles the source against the new contract and reports exactly what broke.
What the generated contract gives you
Section titled “What the generated contract gives you”GeneratedWorkspaceContext— a typedDbContextover the workspace’s runtime tables, with exact mappings to physical table and column names.- Typed entity classes and child-table row classes for every active entity definition, with typed accessors per field kind.
- Stable constants for entity ids, table ids, field ids, field keys, and physical column names.
- The current Entity Definition search-target declarations in the generated
schema configuration, emitted as
SearchField(...)andSearchSystem(...), so Check and Build use the same workspace contract. - A DI extension that registers the context and platform services.
- XML documentation for supported Moltaro assemblies, used automatically by server-side hover and signature help and published in the curated .NET reference.
The contract is a build input generated by Moltaro, not user-owned source — you never download or maintain it in an API-driven workflow. Moltaro adds the current contract to every language-service, Check, and Build snapshot.
Presentation metadata, including responsive Card item spans, stays in Entity UI configuration. Net Operation Project code works with the generated typed records and must not treat the current Card column count as a business-logic contract; the runtime chooses it from the available page or drawer width.
A Date and time entity field is generated as nullable
System.DateTimeOffset. The generated EF model maps it to one PostgreSQL
timestamp(6) with time zone column. Moltaro normalizes writes to UTC and
microsecond precision before saving, so project code may supply a non-zero
offset but should compare and reason about the resulting instant rather than
the original offset.
A String or Text field with the Markdown property label is generated as a
nullable string. The property contains the original Markdown source. Moltaro
maintains its display-safe plain-text projection internally and uses that
projection for presentation, search, projections, and audit previews; links
contribute their visible label, not their destination. Write the property and
call the generated context’s normal SaveChanges method so source validation,
the projection update, and the database writer contract remain atomic. Raw SQL
writes to governed Markdown columns are unsupported and are rejected.
A String field with the TimeZone property label is generated as a nullable
string containing the canonical IANA identifier stored by Moltaro. Its
semantic role is retained in direct-database audit evidence. Treat the value as
a closed catalog identifier. The generated context canonicalizes aliases and
rejects unknown identifiers on SaveChanges and SaveChangesAsync, including
owned table rows; raw SQL is not a supported mutation path.
The same generated-context save boundary enforces active Board status
invariants for existing Entity records used as a Board Target or Board Data.
Moltaro checks the complete tracked proposed root and owned-table state across
all governing Boards before persistence. If any Board rejects the state,
SaveChanges rolls back and throws MoltaroPreCommitSaveRejectedException.
Catch it when the function must return a controlled failure and use its ordered
Errors; the same contract also carries rejections from future non-Boards
providers. Do not parse the exception message. Creating a new record has no
pre-existing governing Board Item. Direct SQL bypasses this protection and is
not a supported Entity mutation path.
Opaque moltaro-attachment://<FileReferenceId> values in Markdown source are
not URLs or access grants. Net Operation Project code does not create Markdown
draft sessions; use the product form workflow when a user must author an inline
image. New ordinary attachments are queued for inspection. Downloads succeed
only for verified Available content and return non-null streamed bytes; the
SDK download result does not expose a backing-storage BlobUri.
Large Managed Cloud files use the provider-neutral
IAttachmentService.UploadStreamAsync/UpsertStreamAsync contract. Supply the
exact size and a stable idempotency key, retry a cancelled transfer from the
start with the same key, and poll GetUploadAsync until IsTerminal.
The key identifies the logical upload. An expired UploadSessionId stays
terminal, but repeating UpsertStreamAsync with a fresh stream and the same
actor, owner, metadata, key, and requested FileReferenceId returns the single
successor physical session. Explicit abort and rejection remain final.
Before opening the source, call GetUploadCapabilitiesAsync to inspect the
effective storage type, maximum size, multipart and part policy, checksum
policy, and extension-aware FileTypeRules. The longest matching extension and
normalized declared MIME must occur in the same rule; the deprecated
AllowedMimeTypes summary is not authoritative. This is a declared-metadata
policy, not antivirus or malware inspection. A pre-session rejection is a MoltaroSdkException;
branch on its stable FailureCode, not its bounded diagnostic message.
Use FileTypePolicyVersion and FileTypePolicyHash from preflight and rejection
metadata to correlate the effective normalized rule set across runtime
processes. For a trusted scheduled import with no known historical author,
leave SourceCreatedByUserId null. Moltaro preserves null on the descriptor,
reference, and relations while the system actor remains separate audit and
authorization provenance. A supplied source user must exist and never grants
access.
Failed with filesystem.upload.providerUnavailable remains resumable: reopen
the source and repeat the same stream call; polling alone does not resume the
provider command. The runtime keeps all S3 credentials and signed URLs outside
project code. This ordinary-attachment path does not raise or bypass the
Markdown image-draft limits.
Auditing from project code
Section titled “Auditing from project code”Automatic save auditing is off for function code and cannot be switched on
per save: field-level audit narrates what users change through the product
surfaces, while your code tells its own story. The supported emit path is
MoltaroDbContext.AddBusinessEventAsync(...), which appends a display-safe
business event to a record’s audit trail; the event then appears in the
record change feed and the WebApp history. The generated contract does not
expose audit rows as queryable DbSets — read history through the API. The
full picture, including the change-feed endpoint and audit settings, is in
Record history and audit.
Services available through DI
Section titled “Services available through DI”Project code uses constructor injection. Alongside the generated context, the runtime provides:
| Service | Purpose |
|---|---|
FunctionContext | Original and actor user ids, operation, correlation id, and function run identity for the current invocation |
MoltaroWorkspaceContext | Workspace metadata: display name, locale, and time zone |
IDevLog | Developer log entries visible in run diagnostics |
IFunctionQueue | Enqueue published functions for background execution |
ISecretService | Resolve administrator-managed outbound credentials from the immutable invocation snapshot |
IMoltaroRuntimeClock | Workspace time |
IUserService, IRoleService, IGroupService | User, role, and responsibility-group list/get/create/update/delete, stable caller-supplied ids, memberships, permissions, blocked state, credentials, and non-authorizing extended data |
IAttachmentService, ICommentService, ITagService | Create and change governed attachments, comments, and resource tags |
IMoltaroResourceEventBus | Publish supported durable resource events |
IBusinessInvariantValidator | Explicitly validate the current existing resource and exact operation before function side effects |
IDynamicEntityGraphQueryService, IDynamicEntityBusinessEventWriter, IDynamicEntityAuditTrailImportService | Supported dynamic-entity traversal, business-event, and explicit import/restore operations |
The lib/ assemblies ship with XML documentation, so every service member
is documented in the IDE; the same documentation is readable from the raw
.xml files for agents working outside an IDE.
Business Invariants
Section titled “Business Invariants”The SDK exposes Business Invariant authoring, analyzer, and deterministic
descriptor-discovery contracts. Administrators configure and enable targets;
enabled compatible targets shape current object operations and guard admitted
Entity mutations. Analyzer purity checks follow source-defined helper calls
reached from Grant. Function execution is not intercepted automatically.
Inject IBusinessInvariantValidator, pass the exact existing resource and
operation with empty parameters, and stop before side effects when the
ordinary ValidationResult is invalid.
Use the SDK operation constants rather than private strings. For example,
single-item Board cycle assignment and whole-cycle rollover share
BoardItemObjectOperationKeys.AssignCycle; a rollover is rejected before any
item moves when one affected item is denied.
Managed secrets
Section titled “Managed secrets”Inject ISecretService into any C# function constructor. Use
GetRequired(key) when missing configuration must fail the invocation, or
TryGet(key, out value) for optional integration configuration. Keys are
case-insensitive. Null, empty, and whitespace-padded keys are programming
errors. Unavailable required secrets throw SecretUnavailableException with
stable Missing, Disabled, or Retired codes.
One invocation always reads one snapshot, so a rotation made while code is running becomes visible only to a later invocation. Never return or log the resolved value. Any trusted C# project that knows a key can resolve it; only allow trusted authors to publish project code.
For the owner/admin lifecycle, exact stable codes, safe outbound handling, and a compile-checked Job, see Managed secrets.
Core services cookbook
Section titled “Core services cookbook”Short patterns for the services above; hover and signature help fill in the rest from the curated XML.
Resolve the current actor or another user (both return MoltaroUser?):
var actor = await users.GetActorUserAsync(cancellationToken);var assignee = await users.GetUserAsync(assigneeId, cancellationToken);Choose the right log target. IDevLog writes developer diagnostics for the
current run; a durable, user-visible history entry is a business event on the
record (see audit):
await devLog.LogInformationAsync("Recalculated credit snapshot", cancellationToken: cancellationToken);await dbContext.AddBusinessEventAsync<Customer>( customer.Id, new MoltaroBusinessEvent("Credit recalculated"), cancellationToken);Enqueue a published global Job and poll it — EnqueueAsync returns a job id,
not a result:
var jobId = await functionQueue.EnqueueAsync("acme.nightly-rollup", new { Scope = "eu" }, cancellationToken);// then poll GET /api/workspace/functions/jobs/{jobId} until a terminal stateAdd governed content to a record through the generated entity type —
comments.CreateAsync<ServiceTicket>(ticket.Id, request, cancellationToken),
and attachments/tags follow the same <TEntity>(entityId, …) shape.
Scheduled jobs attribute new tags to the reserved
moltaro-system-automation actor without requiring a workspace user record.
Set SourceCreatedByUserId only for import or restore when preserving an
existing workspace user as the historical author. If that user does not
exist, ITagService throws MoltaroSdkException with
MoltaroTagErrorCodes.SourceCreatorNotFound; job diagnostics retain that
stable reason code without exposing database constraint details.
Moltaro validates tag permissions with the effective actor. Scheduled
automation uses the platform’s owner/admin system envelope only when the
function invocation carries platform-issued trusted-system provenance; the
reserved actor string cannot grant that envelope to HTTP or resource-event
callers. Workspace migrations also reject a real user with the reserved id.
OriginalUserId is retained only as attribution and is never substituted for
authorization. A repeated complete-set replacement is idempotent, concurrent
replacements for one resource are serialized, and tag mutation events preserve
the function run, version, correlation, and original-user origin used by entity
activity and Board audit/outbox processing.
EntityInstance tags and BoardItem tags have independent feature flags:
EntityDefinition.TagsEnabled and Board.TagsEnabled. Ordinary BoardItem tag
writes are open-item operations. For a terminal BoardItem, use the trusted
IBoardAutomationCommandService.ReconcileHistoricalItemTagsAsync batch.
Add preserves existing names; ReplaceManagedSet changes only an explicit
managed-name allow-list, so manual tags stay intact. The batch commits each
owner separately and returns structured partial outcomes; it does not reopen,
move, or change Board Data, completion, history, or the item row version.
In-app notifications are not a Net Operation Project surface:
IMoltaroNotificationPublisher is intentionally not injectable — use IDevLog
and business events instead.
Application automation vs trusted direct-DB runtime
Section titled “Application automation vs trusted direct-DB runtime”Principals, Boards, and Entitlement Operations expose two deliberate C# levels. Choose the application automation interfaces for normal Net Operation Project code:
| Level | Use it when | What it owns |
|---|---|---|
ApplicationAutomation (preferred) | A function must perform the same complete operation as the Moltaro application | Target and module validation, SQL authorization, system actor provenance, module-native concurrency/idempotency semantics, audit and origin metadata, business/resource events, outbox, and attention projections |
TrustedDirectDb (advanced) | Trusted package-style code intentionally owns database and application orchestration | Package domain rules and direct database work only; the caller owns every missing application side effect |
The machine-readable distinction is in each entry returned by
GET /api/workspace/admin/net-operation-project/developer-surface: inspect
ServiceKind, Preferred, SupportedFunctionContracts,
ExecutionSemantics, and DocumentationUrl. Public CLR visibility by itself
is not a support promise.
Preferred Entity service (Moltaro.Package.NET.Automation):
| Service | Purpose |
|---|---|
IEntityAutomationCommandService | Governed create, update, archive, restore, delete, merge, import, bulk update, responsibilities, tags, comments, and attachments with durable OperationKey replay, optimistic concurrency, lifecycle audit, and application side effects |
Preferred Boards services (Moltaro.Package.NET.Boards.Automation):
| Service | Purpose |
|---|---|
IBoardAutomationCommandService | UI-equivalent add, movement, removal, cycle assignment, links, responsibilities, Board Data, due dates, durable 1–500 item historical import, terminal-safe historical Board Data and managed-tag reconciliation, and guarded historical identity recovery with the complete application flow |
IBoardAutomationQueryService | Board/target discovery, open-item lookup, historical source-key and recovery-state lookup, move validation, current item, and current RowVersion |
Principal CRUD services (Moltaro.Package.NET):
| Service | Purpose |
|---|---|
IUserService | User list/get/create/update/delete, caller-supplied stable ids, exact-Unicode names, blocked state, role membership, password activation, and extended data |
IRoleService | Role list/get/create/update/delete, caller-supplied stable ids, user/permission replacement, and extended data |
IGroupService | Responsibility-group list/get/create/update/delete, user membership, and extended data |
Principal mutations own their transaction, serialize with authoritative Entity authorization, and atomically commit the principal rows, cache invalidation version, and applicable user-index outbox row. They cannot run inside an active package transaction.
Repeatable integrations call Get*Async and then Create*Async or
Update*Async. Update requests are complete desired state: RoleIds is
applied literally and revokes any role missing from an explicit list, while
null preserves the current memberships. Moltaro deliberately does not expose
a parallel principal synchronization facade or batch preflight service.
Preferred Entitlement services
(Moltaro.Package.NET.EntitlementOperations.Automation):
| Service | Purpose |
|---|---|
IEntitlementAutomationCommandService | Grant, renew, suspend, resume, revoke, expire, consume, reverse, adjust, and renewal-operation lifecycle with durable idempotency |
IEntitlementAutomationQueryService | Grant preview, access evaluation, history and ledger snapshots, limit state, and renewal-operation state |
Application automation has fixed semantics:
- It is supported in
Action,TriggerHandler,Command,Job, andHttpEndpointfunctions.ValidationandBeforeSaveMutationreturnmoltaro.automation.executionPhase.unsupported. - The application call persists as
moltaro-system-automation. The original user, function run, function/version, and correlation are retained in origin and audit metadata; request DTOs intentionally have noActorUserId. - Entity
ArchiveAsyncandRestoreAsynctakeEntityIdentityCommandRequest. Reuse itsOperationKeyonly for an exact retry and supply the currentRowVersion. Success returns anEntityLifecycleMutationReceiptwith the next row version, no Entity field values, andIsIdempotentReplay. Scheduled Jobs do not require an original user, and Schedule/Trigger/Function origin is retained without duplicating lifecycle audit or resource events on replay. - Entry to an interactive function is authorized before its code runs. The module call does not impersonate or re-authorize that original user.
- Each call creates a separate application scope and transaction. It does not
join arbitrary pending changes in an injected
DbContext. Save those changes first, or invoke the facade from an after-commit trigger. - A successful return means the facade’s main transaction committed. Ordinary
Boards commands intentionally use normal Runtime API semantics and do not add
a separate idempotency receipt; query current Board state before retrying an
unknown outcome. Historical import instead uses a durable, case-sensitive
SourceKey: query it withGetHistoricalImportAsyncor safely replay the batch. When one legacy Entity Definition target already has a Board pass, readGetHistoricalRecoveryStateAsync, use exactly its recommended mode and item/row-version guards withRecoverHistoricalItemAsync, and inspect the outcome. After an unknown recovery result, retry that guarded request or query the source identity. Entitlement commands require a stableIdempotencyKey, andReplayed = truemeans their native durable result was returned. Use the returnedRowVersionfor the next mutation. FollowUpOperationIdscontains only operations that were actually queued. When a function job id is returned, pollGET /api/workspace/functions/jobs/{jobId}. Do not infer completion from the C#Taskalone.
The older IBoardRuntimeCommandService,
IBoardRuntimeDefinitionProvider, IEntitlementRuntimeCommandService,
IEntitlementRuntimeGrantPreviewService,
IEntitlementRuntimeAccessService,
IEntitlementRuntimeHistoryQueryService,
IEntitlementRuntimeLimitWindowService,
IEntitlementRenewalPolicyService, and
IEntitlementRenewalOperationService remain supported advanced
TrustedDirectDb interfaces. They are not the recommended route for a C#
trigger because they do not promise the WebApp/application orchestration
listed above.
This distinction includes transition link prerequisites: the advanced Boards package can create configured links to existing Board items during a move, while atomic creation of a new target item plus its link and move is provided by the Runtime API application adapter.
Currency Rates (Moltaro.Package.NET.CurrencyRates) exposes
ICurrencyRatesRuntime. It reads settings, provider readiness, and local cache
only, then resolves same/direct/inverse/cross rates with provider priority and
historical fallback. It never performs a network refresh from project code.
The complete machine-readable allow-list is
GET /api/workspace/admin/net-operation-project/developer-surface. See the
runtime recipes for
Boards, Entitlement Operations, Currency Rates, and explicit audit events.
Project-owned services are registered from a startup class declared with assembly attributes:
using Microsoft.Extensions.DependencyInjection;using Moltaro.Operational.Generated;using Moltaro.Package.NET.Functions;
[assembly: MoltaroNetOperationProject(typeof(GeneratedWorkspaceContext))][assembly: MoltaroNetOperationProjectStartup(typeof(Moltaro.Operational.MoltaroStartup))]
namespace Moltaro.Operational;
public sealed class MoltaroStartup : IMoltaroNetOperationProjectStartup{ public void ConfigureServices(IServiceCollection services) { services.AddScoped<ITicketRoutingService, TicketRoutingService>(); }}Registered services can then be injected into any function or data source in the project.
Startup is only for project-owned service types. Services listed by the installation-local developer-surface endpoint are already registered by the generated contract and Moltaro host; inject them instead of adding, removing, replacing, or decorating their descriptors. Check and Build apply the same reserved-service validation used by runtime execution.
For common core platform types in the analyzer catalog, statically identifiable,
unconditional AddSingleton, AddScoped, and AddTransient registrations are
reported as MOLTARO016, including keyed and non-generic overloads. The complete
developer surface is installation- and module-specific, so the exact runtime
diff is authoritative for every generated and host descriptor. It also covers
conditional TryAdd* calls, raw descriptors, removal, replacement, decoration,
and registrations hidden behind extension methods. Check/Build fail when those
operations mutate the host baseline, with reason code
netOperationProject.startup.reservedPlatformServiceMutation and safe metadata
identifying the service, mutation, descriptor, and startup type.
The Net Operation Project status response includes
ActiveArtifactRuntimeStatus, an activation preflight with the active
revision/build/artifact ids and a stable compatibility reason code. Function
run and queued-job operation records include FailureReasonCode or
LastFailureReasonCode together with their captured Net Operation Project
revision, build, and artifact ids, so startup activation failures are distinct
from failures inside user code.
Every failed terminal run has a non-empty stable reason code. Moltaro preserves
the exact code from a typed SDK or platform failure; an ordinary unhandled
runtime error uses moltaro.functionRuntime.unhandled. Queued retries and the
terminal failed job retain the same code in LastFailureReasonCode. Treat the
code as the machine-readable diagnostic contract and do not parse localized or
administrative error text.
Managing the project through the API
Section titled “Managing the project through the API”Everything the Development page does is available through the
Configuration API under
/api/workspace/admin/net-operation-project:
| Endpoint | Purpose |
|---|---|
GET /status | Project status; bootstraps the starter revision if needed |
GET /source-tree | Source tree of the working or requested revision |
GET /source-files | One source file by revision and path |
POST /source-revisions/manual-edit | Create a manual-edit revision from file changes |
GET /source-templates | List template ids, default folders, and required inputs |
POST /source-templates/preview | Preview generated C# without creating a revision |
GET /developer-surface | Supported assemblies, versions, injectable services, generated-contract behavior, and reference links |
GET /builds, GET /builds/{buildId} | Build and check history with diagnostics |
POST /builds | Queue a build or a check of the working revision |
POST /source-language/completions | C# completions for an unsaved source buffer |
POST /source-language/diagnostics | C# diagnostics for a source buffer |
POST /source-language/hover | Symbol signature and XML documentation for a source buffer |
POST /source-language/signature-help | Call signature and parameter documentation for a source buffer |
GET /source-language/source-index | Read-only classification and navigation index |
GET /download | Generated project ZIP for the current or requested revision |
POST /upload | Upload a project ZIP as a new immutable revision |
For API-driven authoring, use all four source-language operations on the
unsaved Content buffer before creating a revision. Include the current
SchemaContractHash from GET /status; a stale value returns HTTP 409 with
netOperationProject.language.schemaContract.stale. Diagnostics use the same
generated-contract project reference, controlled assemblies, C# options, and
analyzers as Check. Every diagnostic identifies its Source or
GeneratedContract origin and includes a stable code and Roslyn location when
available. Diagnostics do not save.
Successful diagnostics and manual-edit responses publish effective source
processing Limits. The current contract supports 500 files, 512 KiB per
UTF-8 file, 5 MiB total source, and 500 changes per manual edit. Diagnostics
deadline failure is HTTP 503 with
netOperationProject.language.analysis.timeout; manual-edit deadline or
bounded project-lock failure is HTTP 503 with
netOperationProject.source.manualEdit.timeout and creates no revision. Size
errors report safe maximum and actual byte counts without source content.
Manual edit creates an immutable revision with optimistic concurrency;
ExpectedContentHash mismatch is HTTP 409. Net
Operation Project numeric values are Build = 0 and Check = 1; Check never
activates, while a successful Build automatically activates and a failed Build
keeps the previous active artifact.
Deployed logic is monitored in the Administration area under the Monitoring group — API Functions, Function operations, and HTTP Endpoints — covered in Runs, jobs, and diagnostics.