feat(solicitation-create): work-order-as-input + canonical labs schema + comprehensive content shape#396
Merged
Merged
Conversation
…a + comprehensive content shape Three bundled rewrites prompted by solicitation 3130 on malaria-itn-app/20260521-1400 where the public page rendered blank Description, "TBD" timeline, "No deadline," Python-list-repr Scope, and zero questions / zero rubric simultaneously. 1. Inputs now read Phase 1's work order (1-design/pdd-to-work-order.gdoc) as the primary content source + decisions.yaml for later run decisions, alongside the PDD (now used for problem-framing only, not for scope). The work order is the comprehensive, opinionated program brief; this skill transforms it into a public-facing solicitation: same comprehensive explanation, less prescriptive (rates → ranges, exact weeks → windows). 2. Field names migrated to the labs canonical schema (per solicitations/models.py @Property accessors): - description (not overview) - application_deadline date string (not response_window_days int) - expected_start_date / expected_end_date (not anticipated_*) - estimated_scale (not sample_target) - questions[].text (not response_questions[].question) - evaluation_criteria[].name/.scoring_guide/.linked_questions (not rubric[].dimension/.criterion) - solicitation_type: 'eoi' lowercase Top-level fields not read by the public-detail template (pass_bar, eligibility_criteria, geographic_scope, per_hh_payment_band_usd, budget) folded into description / scope_of_work prose instead. 3. Content shape demands comprehensive prose: description 500-800 words foundation-pitch tone; scope_of_work 600-1000+ words derived section-by-section from the work order with explicit de-prescription rules; every question has a required framing field; every evaluation criterion has a required scoring_guide + linked_questions. 4. New Step 7a — curl-the-public-URL structural verifier — catches field-name drift at write time instead of at human-eye time. Removal criteria: keep until the labs MCP ships create_solicitation_from_brief (server-side composition), at which point this skill collapses to ~30 lines passing the structured brief. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
jjackson
added a commit
that referenced
this pull request
May 22, 2026
Walks back the "future labs-side create_solicitation_from_brief" direction floated in the previous PR. Operator chose to keep composition in ACE so this skill retains full control over voice, archetype-branched scope, framing/scoring_guide quality, and decisions-log integration (all ACE-context that labs would have to learn). Labs's tightened MCP (2026-05-22 deploy) is the right server-side contribution: create_solicitation + update_solicitation now validate the canonical schema and fail loudly with INVALID_SCHEMA + error.details.fields keyed by JSON-path (e.g. evaluation_criteria[0].linked_questions). Schema enforcement, not content generation. Changes: - New top-level design-principle callout at the start of ## Process: "ACE owns composition; labs validates the schema." Documents the contract + how to read INVALID_SCHEMA responses + when to re-read tools/list inputSchema as the source-of-truth. - Step 6's payload-rejection paragraph updated: labs now rejects unknown top-level fields at write time (post-deploy); error.details surfaces the offending field path. Do not retry with the same payload; do not stuff extras into free-form fields. - Change Log entry removes the "Removal criteria: keep until labs ships create_solicitation_from_brief" line from PR #396 — this skill is the long-term home for solicitation composition. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2 tasks
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.
Summary
Three bundled rewrites of `skills/solicitation-create/SKILL.md` prompted by solicitation 3130 on `malaria-itn-app/20260521-1400` where the public page rendered blank Description, "TBD" timeline, "No deadline," Python-list-repr Scope, and zero questions / zero rubric simultaneously.
1. Work-order-as-primary-input
The skill now reads Phase 1's work order (`1-design/pdd-to-work-order.gdoc`) as the comprehensive content source, plus `decisions.yaml` for any later run-level decisions, alongside the PDD (now used only for problem-framing). The work order is the opinionated program brief; this skill transforms it into a public-facing solicitation — same comprehensive explanation, less prescriptive (rates → ranges, exact weeks → windows).
2. Canonical labs schema
Field names now match `solicitations/models.py`'s @Property accessors. Adding fields the template doesn't read silently does nothing (the labs API echoes any extra keys back without surfacing the drift). Migrated:
Removed top-level fields not read by the public-detail template (`pass_bar`, `eligibility_criteria`, `geographic_scope`, `per_hh_payment_band_usd`, `budget`) — their content folds into `description` / `scope_of_work` prose instead.
3. Comprehensive content shape
4. New Step 7a — public-page structural verifier
After publish, curl the public URL and grep for the rendered Description body, parseable Application Deadline, non-TBD Timeline, markdown-bulleted Scope, and the question + criterion count strings. Any miss → `[BLOCKER]` naming the probable field-name drift. Catches the silent-echo failure mode where the labs API accepts the create cleanly but the public page is empty.
Removal criteria
Keep until the labs MCP ships `create_solicitation_from_brief` (server-side composition via labs's existing `commcare_connect/ai/agents/solicitation_agent.py`). At that point this skill collapses to ~30 lines passing the structured brief.
Test plan
🤖 Generated with Claude Code