change_status cannot say why an application ended, and the API description the tests check against has drifted #16
Labels
No labels
bug
documentation
enhancement
security
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo-mcp#16
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found on 2026-09-29 in a read-only review of postulo-mcp at
0b29e70b9, comparingtests/openapi.jsonwith the description generated from postulo 95348908d.The core's
POST /applications/{pk}/statustakes anend_reasonwithrejected,withdrawnorghostedsince #239, and the insights and the job-search report read it.change_statussends onlystatusandnote, so an ending recorded through an agent never carries a reason. The tests did not notice because the API description they are held to is a snapshot from before that change, and nothing compares it with the core.src/postulo_mcp/server.py:275-283(change_status);tests/fake_api.py:17-25(the refresh recipe and "The snapshot in the tree was taken at postulo 5ee31c66a");tests/openapi.jsonchange_status(status="rejected", note=...); the ending lands on the timeline with no reason, soapplications/endings.py(read byapplications/analytics.pyandapplications/reports.pyin the core) counts it as an ending without a reason. A reason learnt later, which the core accepts asend_reasonsent with the status the application already has (api/schemas.py:494-501), cannot be added through the agent either.StatusInlacksend_reason; the description lacksGET /offers,GET /offers/{pk},POST /listings/{pk}/events,PATCHandDELETE /reminders/{pk},GET /listings/choicesandPUT /captures/{pk}/rendering; the list calls the MCP uses gainedafter_idandupdated_since; and the refusal responses are not problem documents. No operation the MCP calls has been removed, so nothing fails today, which is the point: the fake can no longer tell this repository that the API grew.end_reason: str = ""tochange_status, with the six values (pay,location,not_a_match,filled_internally,my_choice,other) and "only with rejected, withdrawn or ghosted" in its description, and send it only when set. Refreshtests/openapi.jsonwith the recipe intests/fake_api.py. Add a scheduled CI job, or a step on a tag, that regenerates the description from the core's main and fails when an operation or request schema this server calls differs from the snapshot.Done when
tests/test_server.pyhas a test that callschange_status(application_id=7, status="rejected", end_reason="pay")and asserts the payload carriesend_reason; against the refreshedtests/openapi.jsonthe fake accepts it, and against today's snapshot it would refuse it.