feat: retarget CCSS tags to state standards via Interstandard; browse by state (Unit 10) - #42
Merged
Merged
Conversation
Active Storage's engine loads the vips variant transformer unconditionally at boot on Rails 8.1, so the app can't even boot without ruby-vips despite not using image variants yet. webmock (test group) is needed to stub the Interstandard HTTP calls added in the next commits. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
Lessons and Topics keep their CCSS StandardTagging as-is; a StateStandardTagging records a retargeted state code alongside it (target framework, state code/statement, relationship, confidence, review state, disputed, provenance, edge_provenance_ref). Re-running the retarget task (next commit) upserts by the unique key and marks a code no longer confirmed `stale_at` instead of deleting it, so review history and retirement flags survive a transient hiccup. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
Thin Net::HTTP client for the Interstandard translator API: submit() posts a bulk retargeting submission, fetch_report() reads its report, poll() backs off between fetches until the submission reaches a terminal status (or times out). Raises Interstandard::Unauthorized on 401, Interstandard::RateLimited (with Retry-After) on 429, and Interstandard::RequestFailed (carrying the API's error code) on anything else non-2xx. Base URL and API key come from config/initializers/interstandard.rb (INTERSTANDARD_URL / INTERSTANDARD_API_KEY env vars). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
standards:retarget[target-framework] submits every CCSS StandardTagging to Interstandard, polls the report, and stores confirmed exact/grade_shifted results via StateStandardTagging; no_confirmed_match and invalid rows are listed in the task's summary and stored nowhere. standards:retarget_all runs it for every framework in INTERSTANDARD_TARGETS (default co-math-2020,tx-teks-math). standards:coverage prints, per framework, the fraction of a grade's lessons with a confirmed state code (grade 5 by default, matching Unit 10's success criterion; a number or "all" for others). RetargetStandardsJob wraps retarget_all for a weekly Solid Queue recurring run (config/recurring.yml), so demotions/retirements on the Interstandard side propagate automatically. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
/states lists target frameworks with confirmed-tagging counts; /states/:framework lists that framework's codes with statements; /states/:framework/:code lists the lessons/topics tagged to it (non-stale, non-retired only), linking back into the existing grade/module/topic/lesson browse hierarchy. Lesson and Topic show pages now display their CCSS codes plus any confirmed state codes, linking to the per-code page. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
…kflow This repo's CI had no test job at all — scan_ruby/scan_js/lint only, so a red test suite never blocked a merge. Add one against a postgres:16 service (DATABASE_URL, mirroring the fleet's ci.yml pattern), installing libvips since Active Storage now requires it at boot. CLAUDE.md documents the new env vars, rake tasks, and the weekly Solid Queue recurring job. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
bin/importmap audit boots the whole app (config/application.rb), which now requires ruby-vips/libvips just to load — the test job already installed it, scan_js didn't and failed on this PR's CI run. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu
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
CommonMath's Grade 5+ lessons/topics now carry state standard codes (Colorado, Texas, and any other framework Interstandard maps) alongside their existing CCSS
StandardTagging, and the app is browsable by state.StateStandardTagging(migration + model): one row per (taggable, target_framework, state_code, standard), with relationship/confidence/review_state/disputed/provenance carried over from Interstandard's edge, plusretiredandstale_atfor lifecycle without deletion.lib/interstandard/client.rb: thinNet::HTTPclient —submit,fetch_report,poll(backoff + timeout) — raisingInterstandard::Unauthorized(401),Interstandard::RateLimited(429, withretry_after), orInterstandard::RequestFailed(anything else) with the API's own error code/message.lib/standards/retargeter.rb: submits every CCSSStandardTagging, stores confirmedexact/grade_shiftedresults, and marks a previously-confirmed rowstale_at(never deletes) when a re-run no longer confirms it.lib/standards/coverage.rb+standards:coverage: the success-criterion query — fraction of a grade's lessons with a confirmed state code.standards:retarget[framework],standards:retarget_allrake tasks, andRetargetStandardsJobscheduled weekly via Solid Queue'sconfig/recurring.yml./states(frameworks + counts),/states/:framework(codes + statements),/states/:framework/:code(tagged lessons/topics, linking into the existing grade/module/topic/lesson hierarchy). Lesson and Topic show pages now display CCSS + confirmed state codes.ruby-vips, unrelated to this feature but blocking any local test run.testjob (this repo had none) against apostgres:16service, gating PRs on the new suite.Env vars needed
INTERSTANDARD_URL— defaults to the production map (https://interstandard.jumpstartlab.com).INTERSTANDARD_API_KEY— required to actually call out; get one from Interstandard's/api_keyspage.INTERSTANDARD_TARGETS— comma-separated target framework slugs (defaultco-math-2020,tx-teks-math).How to run
Post-Deploy Monitoring & Validation
Run
standards:retarget(orretarget_all) onceINTERSTANDARD_API_KEYis set in production — nothing runs automatically until then beyond the weekly scheduled job. Watch the task's own stdout for401/429errors surfacing asInterstandard::Unauthorized/Interstandard::RateLimited— a 401 means the key is missing/revoked, a 429 means the request-rate or submission-frequency cap was hit and the task should be re-run later, not retried immediately. Validate withstandards:coverage— it should report a non-zero fraction of Grade 5 lessons with a confirmed code for each configured framework.🤖 Generated with Claude Code
https://claude.ai/code/session_011EqZeVdG5q6KDS1Q8sbcxu