[CLI] Add semantic application-contract diffing with gowdk changes
Priority
Medium-high — reviewability, safer upgrades, and deployment planning
Context
GOWDK already exposes rich structured information through routes, endpoints, manifests, compiler inspection, contracts, security audit output, OpenAPI/AsyncAPI, and generated build reports. Security auditing also has focused diff behavior.
What is missing is a single user-facing command that compares two validated application snapshots and explains the operational and compatibility impact of a change before deployment.
A textual source diff cannot reliably answer questions such as:
- Was a public route removed or only moved between source files?
- Did an endpoint change method, path, input contract, guard, CSRF, cache, or result policy?
- Did a page move from static output to request-time rendering?
- Did a target begin requiring a runtime environment variable?
- Did an event stop invalidating a query?
- Must split frontend and backend artifacts be deployed together?
Goal
Add gowdk changes, a semantic diff command that compares normalized validated application plans or versioned build metadata and classifies changes by compatibility, security, runtime, deployment, and informational impact.
Proposed CLI
# Compare the working tree with another Git revision.
gowdk changes --against main
gowdk changes --against HEAD~1 --target site
# Compare two committed build snapshots/reports.
gowdk changes \
--from dist/previous/gowdk-build-report.json \
--to dist/current/gowdk-build-report.json
# CI policy.
gowdk changes --against origin/main --fail-on breaking
gowdk changes --against origin/main --fail-on security,breaking
# Machine-readable output.
gowdk changes --against main --json
Git integration should remain an adapter around snapshot materialization. The semantic comparison engine should accept two already-normalized snapshots without requiring Git, making it reusable by tests, release tooling, and editors.
Change classifications
Use stable machine-readable categories and severities. A possible model:
Compatibility
breaking: an existing consumer/request/deployment can stop working;
potentially_breaking: impact depends on application/runtime behavior;
compatible: additive or behavior-preserving;
informational: metadata-only or non-contract change.
Domains
route;
endpoint;
page_runtime;
component_client;
asset;
security;
cache;
environment;
contract;
realtime;
deployment;
schema;
tooling.
Example human output:
BREAKING route Removed GET /customers/{id}
SECURITY endpoint POST /account/delete no longer has auth.required
RUNTIME page /dashboard changed from static SPA to SSR
CONFIG environment SESSION_KEY became required at runtime
BREAKING contract UserDisabled no longer invalidates CurrentUser
COMPAT endpoint Added GET /health/details
INFO asset hero.css content hash changed
Every finding should include old/new source locations where available and stable identifiers suitable for editor navigation.
Minimum comparison surface
Routes and pages
- route add/remove/change;
- dynamic parameter name/type/rest changes;
- localized route additions/removals;
- static/SPA/SSR/hybrid lane changes;
- guard/public-access changes;
- route-local error page changes;
- cache/revalidate changes;
- page removal or ownership movement.
Endpoints
- kind, method, path, symbol, package, and binding-status changes;
- input field/type/required/validation changes;
- route parameter and query contract changes;
- result/status/content-type changes when represented;
- guard, CSRF, rate-limit, body-limit, CORS, and error-policy changes;
- fragment target/patch behavior changes;
- missing-handler/stub policy changes.
Environment and runtime
- required/optional environment variable additions/removals;
- build-time versus runtime requirement changes;
- generated runtime import/dependency changes;
- server timeout/body/header policy changes that affect generated output;
- lifecycle service additions/removals;
- target role changes.
Contracts and realtime
- command/query/event/job add/remove/rename;
- web exposure and role changes;
- input/output type changes;
- event subscriber/owner changes;
- invalidation edge changes;
- realtime subscription and audience policy changes;
- worker/cron target selection changes when supported.
Assets and client behavior
- public logical asset URL removal/change;
- generated client runtime capability changes;
- component island/WASM ABI changes;
- persisted store key/shape changes where represented;
- page preload/prefetch behavior changes;
- asset cache-policy changes.
Deployment
- target add/remove/rename;
- one-binary versus split/backend-only shape changes;
- frontend/backend compatibility identity changes;
- Docker/base/runtime-user changes;
- generated recipe contract changes;
- runtime feature introduced into a formerly static-only target.
Diff engine design
The engine should compare stable semantic keys rather than array positions or source-file order. It should consume the canonical application plan from #667/#668 and/or a versioned portable snapshot schema.
Suggested internal shape:
type Change struct {
Code string
Severity Severity
Compatibility Compatibility
Domain Domain
Subject SubjectRef
Before any
After any
Message string
OldLocation *source.Location
NewLocation *source.Location
Guidance string
}
Change codes must be stable and documented so CI can waive or target specific rules without parsing messages.
Policy and CI
Support:
--fail-on by compatibility class/domain/severity;
--allow <change-code> or a reviewed policy file;
- baseline/waiver expiry similar to audit policy where appropriate;
- JSON output with a versioned schema;
- deterministic ordering;
- exit codes documented for no changes, allowed changes, policy failure, and invalid comparison input.
The default command should report changes without claiming every semantic change is a SemVer break. GOWDK remains 0.x, but users still need precise operational impact.
Snapshot acquisition
Support two sources:
- Source snapshots: compile the working tree and another revision into validated plans without publishing output.
- Artifact snapshots: compare versioned metadata embedded in prior/current build outputs.
For Git revisions, avoid mutating the user's checkout. Use a temporary worktree/archive or Git object reads, and run through the canonical workspace/compiler pipeline from #671.
External config/build execution for an untrusted revision must be explicit. A safe default may compare static/declarative metadata first and require a flag before executing revision-owned Go configuration or build functions.
Security considerations
- Do not automatically execute arbitrary code from an untrusted comparison revision without explicit consent and clear output.
- Redact secret-like config values.
- Treat guard removal, public exposure, CSRF disablement, relaxed CORS, raw HTML exposure, and role weakening as security-domain changes.
- Never infer backend resource authorization solely from declarative route metadata.
Editor integration
The JSON output should support a future VS Code view that groups changes and navigates to old/new declarations. Editor integration is not required for the first CLI slice, but source references and stable codes should be designed now.
Test plan
Golden and integration cases should cover:
- route removal/addition/parameter changes;
- endpoint method/path/input/result changes;
- guard and CSRF weakening;
- static-to-SSR transition;
- cache and revalidation changes;
- environment requirement changes;
- command/query/event/invalidation changes;
- asset logical URL removal;
- split target mismatch/deployment-shape changes;
- equivalent plans with reordered source discovery producing no changes;
- source move with stable semantic identity;
- JSON schema validation and deterministic ordering;
--fail-on exit behavior;
- waiver/policy behavior if included;
- comparison against a Git revision without modifying the checkout;
- refusal or explicit consent for executable config in an untrusted revision.
Non-goals
- Replacing
git diff for source review.
- Guaranteeing application-level database or business compatibility.
- Inferring authorization correctness inside user-owned Go handlers.
- Automatically generating migration code.
- Treating all 0.x API changes as forbidden.
Acceptance criteria
Related
[CLI] Add semantic application-contract diffing with
gowdk changesPriority
Medium-high — reviewability, safer upgrades, and deployment planning
Context
GOWDK already exposes rich structured information through routes, endpoints, manifests, compiler inspection, contracts, security audit output, OpenAPI/AsyncAPI, and generated build reports. Security auditing also has focused diff behavior.
What is missing is a single user-facing command that compares two validated application snapshots and explains the operational and compatibility impact of a change before deployment.
A textual source diff cannot reliably answer questions such as:
Goal
Add
gowdk changes, a semantic diff command that compares normalized validated application plans or versioned build metadata and classifies changes by compatibility, security, runtime, deployment, and informational impact.Proposed CLI
Git integration should remain an adapter around snapshot materialization. The semantic comparison engine should accept two already-normalized snapshots without requiring Git, making it reusable by tests, release tooling, and editors.
Change classifications
Use stable machine-readable categories and severities. A possible model:
Compatibility
breaking: an existing consumer/request/deployment can stop working;potentially_breaking: impact depends on application/runtime behavior;compatible: additive or behavior-preserving;informational: metadata-only or non-contract change.Domains
route;endpoint;page_runtime;component_client;asset;security;cache;environment;contract;realtime;deployment;schema;tooling.Example human output:
Every finding should include old/new source locations where available and stable identifiers suitable for editor navigation.
Minimum comparison surface
Routes and pages
Endpoints
Environment and runtime
Contracts and realtime
Assets and client behavior
Deployment
Diff engine design
The engine should compare stable semantic keys rather than array positions or source-file order. It should consume the canonical application plan from #667/#668 and/or a versioned portable snapshot schema.
Suggested internal shape:
Change codes must be stable and documented so CI can waive or target specific rules without parsing messages.
Policy and CI
Support:
--fail-onby compatibility class/domain/severity;--allow <change-code>or a reviewed policy file;The default command should report changes without claiming every semantic change is a SemVer break. GOWDK remains 0.x, but users still need precise operational impact.
Snapshot acquisition
Support two sources:
For Git revisions, avoid mutating the user's checkout. Use a temporary worktree/archive or Git object reads, and run through the canonical workspace/compiler pipeline from #671.
External config/build execution for an untrusted revision must be explicit. A safe default may compare static/declarative metadata first and require a flag before executing revision-owned Go configuration or build functions.
Security considerations
Editor integration
The JSON output should support a future VS Code view that groups changes and navigates to old/new declarations. Editor integration is not required for the first CLI slice, but source references and stable codes should be designed now.
Test plan
Golden and integration cases should cover:
--fail-onexit behavior;Non-goals
git difffor source review.Acceptance criteria
gowdk changescompares two normalized application snapshots without relying on textual source order.--fail-on.Related
gwdkir.Programinto semantic IR and target-specific plans #668 — canonical validated plan boundaries