fix(contracts): close gate-identifier violations in openapi.yaml (84 -> 0) - #156
Open
izzywdev wants to merge 2 commits into
Open
fix(contracts): close gate-identifier violations in openapi.yaml (84 -> 0)#156izzywdev wants to merge 2 commits into
izzywdev wants to merge 2 commits into
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
gate-identifier(identifier-standard.md §1) requires every create-body schema to setadditionalProperties: false, so a stray field can never bind. 28 POST/PUT operations incontracts/openapi.yamldeclaredadditionalProperties: truewith nopropertiesat 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(andcontainer_manager.pyforcreateAgentContainer) that actually implements the route, took the exact fields it reads — the Pydantic model's fields, or the individualBody(...)/Form(...)params for handlers that don't use a model — wrote those into the OpenAPI schema, and setadditionalProperties: 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/_idin the request body, so no §1 id-removal was needed.gate-identifier's §3 (polymorphic reference) check also reported 0 findings — the repo has noentityId/ownerId/etc.-shaped fields.One correction beyond the identifier standard itself: 3 of the 28 (
uploadOrganizationDocument,uploadTeamDocument,uploadAgentDocument) were declared asapplication/jsonin the spec, but their handlers takeUploadFile = 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 tomultipart/form-datawith the real field set (file,title,tags) andadditionalProperties: 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.yamlanddeploy/helm/fuzeagent/files/openapi.yamlwere regenerated fromcontracts/openapi.yamlviascripts/sync-chart-files.sh(not hand-edited);scripts/sync-chart-files.sh --checkpasses.info.versionbumped0.1.0->0.2.0pergovernance/versioning.md(the repo'sgate-versioncheck, 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:
After:
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).md5sum+sync-chart-files.sh --check).Not verified: the repo's
pytestsuite (services/orchestrator/tests/) could not be run in this sandbox —conftest.pyimportsmain_with_hierarchy.py, which pulls insentence-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 onlocalhost:5434that 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: falserejects 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 emptyadditionalProperties: falseobject (client must send{}or omit the body), matching current reality.createAgentFromTemplate/addOrganizationalKnowledge— these handlers use a rawdictparam / individualBody(...)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-idexemptions — every flagged operation had a concrete, unambiguous handler to read.x-client-assigned-id added
None.
Generated by Claude Code