Created
Jul 08, 02:40
Started
Jul 08, 02:47
Completed
Jul 08, 07:12
DevOps handoff
Type
Feature
Shape
library
Worktree Slug
model-page-engine-protocol
Repositories
studio-engine
Release Slug
—
Branch
feat/model-page-engine-protocol
Pull Request
https://github.com/amcritchie/studio-engine/pull/12Local URL
—
QA URL
—
Production URL
—
Acceptance Criteria
Expected Test Plan
Checks Run
How long this task spent in each testing phase — Build → Local Certification → CI → Review → Operator Acceptance.
Build
about 1 hour
Completed
Local Certification
—
Missing
CI
—
Missing
Review
about 2 hours
Completed
Operator Acceptance
—
Missing
Stage Timeline
Who handled each stage, the time it took (measured), and the model / tokens / cost reported (best-effort) — plus who's on it right now. — means the agent didn't report that metric.
Conversation
QA review feedback, agent handoffs, and follow-up notes for this task.
Scout report: merge-ready - Light review (blockchain/library lens): admin-gating, registry-constantize, JSON-exposure, route-order all sound. No blockers. Reporter: jasper Outcome: merge-ready Findings: - require_admin correctly applied and fails closed: Studio::ModelsController mirrors existing Studio::EmailImagesController pattern; require_admin (error_handling.rb:163) redirects non-admins/guests; runs BEFORE load_page so no model-existence oracle. - No constantize: ModelPage.new resolves params[:model] via registry.fetch{raise UnknownModel}->404; only host-registered live class refs reachable. Empty-registry claim holds. - No stored-XSS: view renders <%= @page.json %> in .html.erb (auto-escaped); copy_button escapes text/data-attr; admin-only surface. - Route order correct: models/:model/random drawn before models/:model/:id with a dedicated regression test. - NON-BLOCKER: record.as_json dumps ALL columns (no only:/except: hook) - fine for admin+opt-in v1, but a sensitive registered model exposes everything; consider attribute-filter in Entry later. - NON-BLOCKER: order(RANDOM()).first is a full-table sort - acceptable for low-volume admin debug, perf smell on large tables. - NIT: version.rb bumped to 0.12.0 but CHANGELOG entry still under '## Unreleased' (Keep-a-Changelog would cut to '0.12.0 - date' on gem release). Questions: - none Checks: - mcritchie consumer CI RED on env-brittle AgentWorktreeTest (unrelated to this diff) - Carl/primary owns that gate call; turf CI green.
Scout report: request-changes - Clean diff, correct pattern; blocked on gates: dor-check RED (full-suite/rubocop cert MISSING) + mcritchie consumer CI RED on unrelated AgentWorktreeTest flake leaves AC#6 unmet; base is main not release. Reporter: carl Outcome: request-changes Findings: - Code is correct and mirrors admin-models host-registry pattern (never constantizes host models by name); 5/6 acceptance met. - AC#6 'consumer CI green in mcritchie' UNMET — red is pre-existing AgentWorktreeTest#test_mcritchie_config_reserves_3020 harness flake (repo missing sibling mcritchie-studio), NOT caused by this diff; must be guarded consumer-side or excepted with sign-off. - dor-check RED: full-suite/rubocop cert MISSING for this SHA — run bin/full-suite-check or record a justified gem [full-suite-bypass]. - PR base is main; studio-engine release == main at SHA 1671e54 (zero drift) — re-point base to release. - NON-BLOCKING: register-in-initializer guidance (model_page.rb:19-21) will empty the class-level @registry on dev Zeitwerk reload — recommend to_prepare; integration test covers only route drawing, not admin-gating/404. Questions: - none Checks: - [unit] model_page_test.rb 10 green - [integration] model_page_routes_test.rb route-draw + random-before-:id green - [ci] turf_monster consumer suite PASS; mcritchie_studio consumer suite FAIL (unrelated AgentWorktreeTest flake)
PR #12: ModelPage code is clean (Carl + Jasper both found no code defects; admin gate fails closed, no constantize leak, no XSS, route ordering correct) — but three gates block. (1) DoR is RED: no fingerprint-bound full-suite/rubocop cert recorded for this SHA — run bin/full-suite-check model-page-engine-protocol (or a justified [full-suite-bypass] note if bin/release-check is the canonical gem suite). (2) AC#6 unmet: mcritchie consumer CI is RED on AgentWorktreeTest#test_mcritchie_config_reserves_3020 (test/lib/agent_worktree_test.rb:53) — a pre-existing env-brittle test that shells to bin/agent-worktree and dies on 'repo missing: .../mcritchie-studio', unrelated to this diff; library-shape DoR requires BOTH consumer suites green, so guard that test to skip when the sibling mcritchie-studio checkout is absent, or get operator sign-off to except the flake and record a [consumer-ci-flake] note. (3) Re-point PR base from main to release (gh pr edit 12 --base release — same SHA 1671e54, zero drift) to avoid an accidental merge-to-main and keep qa-release-sweep semantics clean. Non-blocking for a follow-up: register-in-initializer guidance will empty the class-level @registry on Zeitwerk dev-reload (point hosts at config.to_prepare); and as_json dumps all columns (add an attribute filter before registering any sensitive model). No ModelPage code changes needed.
Review gates addressed: (1) PR #12 base re-pointed main->release (zero drift, SHA 1671e54). (2) DoR full-suite cert: bin/release-check is the canonical studio-engine suite (green, 13 tests incl. new); a gem has no bin/full-suite-check/rubocop lane -> recorded [full-suite-bypass]. (3) AC#6 consumer-CI flake (AgentWorktreeTest#test_mcritchie_config_reserves_3020, repo-missing) is pre-existing + unrelated to this diff -> awaiting operator decision: except-with-signoff vs guard-the-test. No ModelPage code changes (Carl+Jasper found none needed).
All three review gates resolved: (1) PR #12 base main->release (zero drift, SHA 1671e54). (2) DoR full-suite cert -> [full-suite-bypass]: bin/release-check is the canonical studio-engine suite, green (13 tests incl. new unit+route). (3) AC#6 consumer-CI flake AgentWorktreeTest#test_mcritchie_config_reserves_3020 (repo-missing) EXCEPTED by operator sign-off as pre-existing + unrelated to this diff [consumer-ci-flake]; guard-the-test chore filed in mcritchie. No ModelPage code changes (Carl+Jasper: none needed). Re-submitting for review.
Scout report: merge-ready - Light read clean: protocol/controller/view/tests match all acceptance bullets; admin-gated via proven require_admin pattern; no constantize of user input; registry ships empty. One acceptance bullet (consumer CI green) unmet AS-WRITTEN: mcritchie lane red on AgentWorktreeTest repo-layout env coupling in mcritchie's own suite, unrelated to this diff; turf lane green. Needs job re-run or mcritchie-side harness fix, not PR rework. Reporter: jasper Outcome: merge-ready Findings: - mcritchie consumer CI failure = AgentWorktreeTest#test_mcritchie_config_reserves_3020 aborting 'repo missing' on runner layout; test lives in mcritchie-studio, known-flaky lane, diff touches no workflow/harness — environmental, supervisor's call to re-run or waive - non-blocker: ModelPage#json uses record.as_json which ignores filter_attributes and DECRYPTS encrypts-declared attrs — document 'never register secret-bearing models' or filter via model.filter_attributes before any app registers wallet-like models - non-blocker: registration in a plain initializer holds live class refs; Zeitwerk dev reload leaves stale classes — recommend documenting to_prepare registration - non-blocker: /models/:model/:id has no :id constraint; dotted identifiers split as format — add id: /[^\/]+/ if dotted slugs ever registered Questions: - none Checks: - gh pr view #12: OPEN, not draft, base release, mergeable - Consumer CI: turf_monster SUCCESS, mcritchie_studio FAILURE (env coupling, evidence in report) - route-order test asserts random drawn before :id catch-all
Scout report: merge-ready - Deep review clean: protocol object + admin-gated controller/view/routes match all 6 acceptance criteria; ran bin/release-check fresh at PR head 17571dc (green); red mcritchie consumer CI verified as exactly the operator-excepted agent-worktree flake (repo-missing on runner), unrelated to this diff; turf consumer green Reporter: carl Outcome: merge-ready Findings: - dor-check red-CI flag is solely the excepted consumer flake (1 failure in 3082 runs, env-gap not diff-related) - advisory non-blocking: record.as_json dumps all attributes (filter_attributes does not apply) — suggest v2 except:/only: registration option before registering secret-bearing models - merge-safety note: PR 11 (docs refresh) also edits CHANGELOG Unreleased region — second-to-merge needs trivial rebase - nit: version bumped 0.12.0 in-PR while CHANGELOG entry sits under Unreleased — stamp dated header at gem publish Questions: - none Checks: - [full-suite] bin/release-check rerun by reviewer in worktree at 17571dc — green - [consumer-ci] mcritchie job log inspected: only AgentWorktreeTest#test_mcritchie_config_reserves_3020 fails (repo missing on runner); turf green
Avi review approved; ready for Steffon's qa-release sweep.
SHIPPED: PR #12 merged to release+main (57b8862); studio-engine 0.12.0 published to RubyGems + tagged v0.12.0. Consumer CI: turf green, mcritchie flake excepted (operator sign-off). Non-blocking follow-ups deferred: register-in-to_prepare (applied in mcritchie adoption), as_json column filter for sensitive models.
Sealed-bid sizing
Edit →Alex (PM)
—
Avi (PO)
MEDIUM
Dev
MEDIUM
Actual
XL
We emailed a one-tap sign-in link to . It expires shortly and can only be used once.
No email? Check spam, or close this and try again.