Skip to content

fix(contracts): close gate-identifier violations in openapi.yaml (84 -> 0) - #156

Open
izzywdev wants to merge 2 commits into
mainfrom
fix/gate-identifier
Open

fix(contracts): close gate-identifier violations in openapi.yaml (84 -> 0)#156
izzywdev wants to merge 2 commits into
mainfrom
fix/gate-identifier

Conversation

@izzywdev

Copy link
Copy Markdown
Owner

What

gate-identifier (identifier-standard.md §1) requires every create-body schema to set additionalProperties: false, so a stray field can never bind. 28 POST/PUT operations in contracts/openapi.yaml declared additionalProperties: true with no properties at all — a placeholder ("the model is Pydantic and not reproduced here") rather than a real schema. That fails the check across all three mechanically-synced copies of the spec: 84 violations = 28 operations x 3 copies.

What changed

For each of the 28 flagged create operations, I read the handler in services/orchestrator/main.py (and container_manager.py for createAgentContainer) that actually implements the route, took the exact fields it reads — the Pydantic model's fields, or the individual Body(...)/Form(...) params for handlers that don't use a model — wrote those into the OpenAPI schema, and set additionalProperties: false. Nothing a working client currently relies on is rejected, because the closed schema is exactly the field set the handler already consumes.

None of the 28 operations declared a client-settable id/uuid/_id in the request body, so no §1 id-removal was needed. gate-identifier's §3 (polymorphic reference) check also reported 0 findings — the repo has no entityId/ownerId/etc.-shaped fields.

One correction beyond the identifier standard itself: 3 of the 28 (uploadOrganizationDocument, uploadTeamDocument, uploadAgentDocument) were declared as application/json in the spec, but their handlers take UploadFile = File(...) + Form(...) fields — i.e. multipart/form-data. A closed JSON schema on those operations would have been meaningless (the real request is never JSON), so I changed the declared content type to multipart/form-data with the real field set (file, title, tags) and additionalProperties: false. This is the same three operations' request bodies I was already rewriting for the identifier standard, not a separate unrelated change.

services/orchestrator/contracts/openapi.yaml and deploy/helm/fuzeagent/files/openapi.yaml were regenerated from contracts/openapi.yaml via scripts/sync-chart-files.sh (not hand-edited); scripts/sync-chart-files.sh --check passes. info.version bumped 0.1.0 -> 0.2.0 per governance/versioning.md (the repo's gate-version check, currently report-only, flags contract changes with no version bump).

Verification

gate_identifier.py — this repo does not vendor its own copy; I ran FuzeSDLC's (scripts/gate_identifier.py) against a fresh clone of this branch:

Before:

gate-identifier: 84 violation(s)
  ✗ contracts/openapi.yaml: POST /agents — create body schema does not set 'additionalProperties: false' (identifier-standard.md 1)
  ... (28 operations x 3 files, all the same C2 message)

After:

gate-identifier: OK

Also checked:

  • openapi-spec-validator — spec is valid OpenAPI 3.
  • helm lint deploy/helm/fuzeagent — passes (the vendored spec is a static mounted file, not consulted by chart templates/values).
  • The three copies are byte-identical (md5sum + sync-chart-files.sh --check).

Not verified: the repo's pytest suite (services/orchestrator/tests/) could not be run in this sandbox — conftest.py imports main_with_hierarchy.py, which pulls in sentence-transformers -> transformers -> tokenizers, and the versions this environment resolved are internally incompatible (ModuleNotFoundError: Could not import module 'GGUF_CONFIG_DEFAULTS_MAPPING') independent of anything in this PR; the suite also requires a live Postgres on localhost:5434 that isn't available here. This PR touches no Python source — only the three OpenAPI spec copies — so the app's actual request validation and handler behavior at these routes is unaffected regardless.

Operations changed (all 28)

createAgent, assignTask, createAgentFromTemplate, createAgentConversation, sendMessageToAgent, submitHumanResponse, registerAgent, approveFileOperations, callMcpTool, setupAgentMcp, initiateTaskCoordination, storeProviderCredentials, configureAgentModel, estimateTaskCost, addOrganizationalKnowledge, createGoal, createMilestone, createTaskFromMilestone, createGoalConversation, addMessageToConversation, recordProgressTracking, uploadOrganizationDocument, addOrganizationUrl, uploadTeamDocument, addTeamUrl, uploadAgentDocument, addAgentUrl, createAgentContainer.

For every one, I confirmed by reading the handler that additionalProperties: false rejects nothing the handler reads. Two worth calling out:

  • registerAgent (POST /agents/{agent_id}/register) — the handler (register_agent) doesn't read the request body at all today; the schema is now an empty additionalProperties: false object (client must send {} or omit the body), matching current reality.
  • createAgentFromTemplate / addOrganizationalKnowledge — these handlers use a raw dict param / individual Body(...) params rather than a Pydantic model, so I declared exactly the field names each reads via .get()/param binding.

Left unfixed / needs an owner decision

Nothing. All 84 violations resolve to 0 with no allowlist entries and no x-client-assigned-id exemptions — every flagged operation had a concrete, unambiguous handler to read.

x-client-assigned-id added

None.


Generated by Claude Code

gate-identifier (identifier-standard.md §1) requires every create-body
schema to set `additionalProperties: false`, so a stray field can never
bind. 28 POST/PUT operations in contracts/openapi.yaml declared
`additionalProperties: true` with no `properties`, which fails that
check across all three mechanically-synced copies of the spec
(84 = 28 x 3).

For each flagged operation, added the properties actually read by its
handler in services/orchestrator/main.py (verified against the
Pydantic model or individual Body(...)/Form(...) params each route
uses) and set additionalProperties: false, so the tightened schema
rejects nothing a working client currently relies on. None of the 28
declared a client-settable id, so no §1 id-removal was needed.

Also corrected 3 document-upload operations (uploadOrganizationDocument,
uploadTeamDocument, uploadAgentDocument) from a bogus application/json
declaration to the multipart/form-data their handlers actually accept
(UploadFile + Form fields), since a closed JSON schema would have been
meaningless there.

Synced services/orchestrator/contracts/openapi.yaml and
deploy/helm/fuzeagent/files/openapi.yaml from contracts/openapi.yaml
via scripts/sync-chart-files.sh, and bumped the contract's info.version
(0.1.0 -> 0.2.0) per governance/versioning.md.

gate_identifier.py (from FuzeSDLC; this repo does not vendor its own
copy) now reports: gate-identifier: OK (was 84 violations).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPa3JgrVNtWrGvqQEAEqv
@izzywdev izzywdev added the auto-merge label Aug 18, 2026 — with Claude
@github-actions
github-actions Bot enabled auto-merge (squash) August 18, 2026 16:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant