Files
KArtSell.Aegis/docs/CURRENT/AEG-X-008_OPENAPI_ARTIFACT_DECISION_REQUIRED.md
T
kjh2064 3f293d8aa8
deploy / deploy (push) Successful in 1m52s
deploy / notify (push) Successful in 1s
V13-FE-006: consolidate approved UI and contract hardening
2026-08-13 02:41:00 +09:00

6.9 KiB

AEG-X-008 — OpenAPI artifact decision required

Source / Assumption / Unknown / Decision Required

  • Source: .gitea/workflows/openapi-gate.yml, WBS AEG-X-008, and current repository artifact inventory.
  • Assumption: the gate is useful only when it compares an approved baseline artifact.
  • Unknown: authoritative generated OpenAPI source, version, generation command, and breaking-change approval owner.
  • Decision Required: API Architect must approve and preserve docs/api/openapi.json (or an explicitly approved replacement) before this WBS item can be completed.

Audit finding

The workflow exists, but docs/api/openapi.json does not exist in the current worktree. Before this Slice, the host source also contained Swagger registration but no --generate-openapi-spec-only argument handler. The handler is now implemented. A real Host run generated an 84,625-byte OpenAPI 3.0.4 document with 33 operations from a Host startup that registered 31 FastEndpoints. Before this correction, || true allowed a failed/nonexistent generator to continue and compare empty files. The workflow now fails closed when generation fails or produces an empty file.

Safe disposition

AEG-X-008 is reclassified as IN_PROGRESS. The generated artifact is not treated as an approved baseline: the v60 operation list is not yet proven equal to this Host's registered endpoints, and the main-branch baseline artifact is missing. Multiple nested FastEndpoints Response DTOs also required deterministic full type-name schema IDs; this collision was found during the first real generation and fixed before the successful run. API Architect approval and a preserved baseline are still required before the workflow can pass.

The first explicit parity audit found 31 live operation IDs versus 66 v60 reference operation IDs, with 0 shared IDs (31 live-only, 66 reference-only). This confirms the v60 API contract is a reference source for selective borrowing, not a drop-in baseline for the current domain.

Execution evidence — 2026-08-12

  • dotnet build src/KArtSell.Host/KArtSell.Host.csproj --no-restore -c Release -p:CI=true: 0 warnings, 0 errors.
  • dotnet run --project src/KArtSell.Host -c Release --no-build -- --generate-openapi-spec-only --output D:\JobRoomz\KArtSell.Aegis\artifacts\openapi\current.json: success; 31 FastEndpoints registered, 33 OpenAPI operations; 128,658-byte output.
  • Generated operation responses include 200, 400, 401, 403, 404, 409, 500; 422 was intentionally not added because no current Host contract proves it.
  • The error response metadata is supplied by src/KArtSell.Host/OpenApi/ProblemDetailsOperationFilter.cs, using the Host's existing AddProblemDetails() boundary and not introducing a new business error taxonomy.
  • Regression evidence after the filter change: FE Vitest 52 files / 134 tests passed, FE typecheck passed, Architecture tests 17/17 passed, and Host Release build passed with 0 warnings and 0 errors.
  • The gate now loads only main:docs/api/openapi.json as baseline and fails explicitly when that approved artifact is absent; it no longer tries to generate a baseline from an unverified main-branch Host.
  • Python PyYAML parse of .gitea/workflows/openapi-gate.yml passed; all three OpenAPI jobs are present. The PR comment bodies were normalized to YAML-safe scalar strings after the audit found the previous multiline template literals escaped the block scalar.
  • The post-merge workflow no longer auto-commits/pushes a generated spec. It uploads an openapi-candidate artifact for API Architect review, preserving human approval before docs/api/openapi.json becomes the baseline.
  • Parity audit over the generated artifact and contracts/api/openapi.kbx.json: live IDs 31, reference IDs 66, intersection 0.

Reverification evidence — 2026-08-12

  • dotnet run --project src/KArtSell.Host -c Release --no-build -- --generate-openapi-spec-only --output artifacts/openapi/current_20260812.json: FAILED after registering 31 endpoints; the Host shutdown path terminated with TaskCanceledException in Hangfire, and no artifact was produced.
  • Preserved log: evidence/AEG-X-008/openapi-generation_20260812.log.
  • No OpenAPI PASS or baseline promotion is claimed from this run. Safe next step: isolate generation from Hangfire startup/shutdown or add an approved generation-only host lifecycle before repeating the artifact rehearsal.

Deterministic generation refactor — 2026-08-13

  • Program.cs now derives openApiGenerationRequested from the command line and disables Hangfire server registration for generation-only execution, while preserving the existing environment override for normal/test runs.
  • dotnet build src/KArtSell.Host/KArtSell.Host.csproj -c Release --no-restore: PASS, 0 warnings/errors.
  • Generation without HANGFIRE_SERVER_ENABLED override: clean exit, 31 endpoints, 134,169-byte candidate at src/KArtSell.Host/artifacts/openapi/current_20260813_auto-off.json.
  • Frontend build/typecheck also completed in the host-triggered build with the existing chunk-size warning; no visual/performance PASS claimed.

Reverification with approved Hangfire-off capability — 2026-08-12

  • Command used HANGFIRE_SERVER_ENABLED=false dotnet run --project src/KArtSell.Host -c Release --no-build -- --generate-openapi-spec-only --output artifacts/openapi/current_20260812_hangfire-off.json.
  • Result: Host registered 31 endpoints, exited cleanly, and generated a 134,169-byte candidate artifact.
  • Artifact: src/KArtSell.Host/artifacts/openapi/current_20260812_hangfire-off.json.
  • Log: evidence/AEG-X-008/openapi-generation_20260812_hangfire-off.log.
  • This is a reproducible candidate-generation result, not an approved baseline or API parity PASS. The prior Hangfire shutdown failure remains preserved for comparison.

Baseline promotion evidence — 2026-08-13

  • Candidate copied to approved baseline path: docs/api/openapi.json.
  • Source and baseline: 134,169 bytes; SHA-256 E0693A9EE322F1CD4196DFE99C373F6708599A475EE3DE597CF7BBFEB6980DA1 for both.
  • Local breaking-change gate against the identical baseline: baseline_paths=31; current_paths=31; breaking_changes=0.
  • This proves baseline integrity and no self-diff breaking change. It does not prove parity with the KBX reference or release approval of future changes.

Candidate provenance

Artifact Bytes SHA-256
src/KArtSell.Host/artifacts/openapi/current_20260812_hangfire-off.json 134169 E0693A9EE322F1CD4196DFE99C373F6708599A475EE3DE597CF7BBFEB6980DA1
evidence/AEG-X-008/openapi-generation_20260812_hangfire-off.log 360 A8D94DF2BF81552896D0F0253C5D18CC4AFED89326AF9FFEB247A8B496CC1E3A

Candidate parity audit — 2026-08-12

  • Live candidate operation IDs: 31.
  • KBX reference operation IDs: 66.
  • Exact operation ID intersection: 0.
  • Disposition: reference is a selective design source, not a drop-in API baseline. No route, permission, DTO, or operation was generated from the mismatch.