From 3bc3abe20944c0297dd6d2956a3f9ff0e9d7734a Mon Sep 17 00:00:00 2001 From: "n.siegfried" Date: Sun, 16 Aug 2026 12:14:45 -0500 Subject: [PATCH] T5.7 - CR-016: Assets off for Micron EUV, by configuration Asset content duplicates the database Clinton's team maintains, and that integration is deferred, so the section comes out in the interim. This is a configuration task, and the wave file says so - "Surface: configuration". There is no Micron EUV SOP in this repository; it is data on a running system. What the repository holds are two representations of the Micron configuration, and both now carry the toggle: wp-creation-app.js SAMPLE_SOP what the standalone creator shows when there is no project SOP to read work-package-suite-app.js loadSample the Micron FMCS SOP the wizard loads For a real project the mechanism is step 12 and needs no code: untick Assets, complete the SOP. That is what T5.5 built and what "another SOP can enable Assets and it works" means. Both write a PARTIAL map - {assets:false} - rather than a full one. WPSections.normalize fills the rest in as ON, so a section added after today is not silently off for this SOP. The probe checks that specifically: exactly one key is false, not nine true and one false frozen at today's list. html/wp-creation-app.js SAMPLE_SOP.sections html/work-package-suite-app.js loadSampleData sets state.sections tests/sections_check.py +13 checks (75 -> 88) Done when [x] Assets does not render for Micron EUV in the form, detail view or export - and not in the section chip strip either, which is the form's contents page [x] the section and its model remain in the codebase - #asset-card and pkgAssets are both still there, checked in the browser rather than assumed [x] another SOP can enable Assets and it works - the fixture project renders it seed_demo.py was deliberately NOT changed. Its SOP row stores a bare {governance: ...} blob rather than the {sop, state} shape pullProject reads, so its data never reaches the creator's SOP object at all - adding sections there would be a toggle nothing consults. That shape mismatch is BL-018 and it should be fixed as one thing, not worked around here. What the probe caught The first run reported on "Job A" while claiming Micron. activeProjectId falls back to ProjectData.getActiveId(), so a project left in localStorage by an earlier navigation sent bootSOP() down the real-project branch and the sample was never loaded - every CR-016 assertion was then measuring the wrong SOP and four of them happened to fail, which is the only reason it was noticed. The probe clears storage first and says why. Verified one at a time sections_check 88/88 (75 + 13 for CR-016) browser_check 71/71 f_items F1-F5 FIXED, F6 REPRODUCES (T7.2) Question for the PR, per CLAUDE.md: CR-009's decision also says Kitting ships toggled off for Micron EUV via these same toggles. That is wave 8's to apply (CR-009/CR-010/CR-012), so the sample still has Kitting on. If the intent was for both to go off together, the second line is one word. Co-Authored-By: Claude Opus 5 (1M context) --- html/work-package-suite-app.js | 12 ++++++++ html/wp-creation-app.js | 10 +++++++ tests/sections_check.py | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/html/work-package-suite-app.js b/html/work-package-suite-app.js index 069354d..c71de16 100644 --- a/html/work-package-suite-app.js +++ b/html/work-package-suite-app.js @@ -432,6 +432,18 @@ function loadSampleData(){ // Step 7 already has defaults + // CR-016 / T5.7. The sample is the Micron EUV configuration, and Micron does not + // use Assets: its content duplicates the database Clinton's team maintains, and + // that integration is deferred. Off by toggle, so the section and its model stay + // in the application for the integration to land in — and any other project can + // turn it back on from step 12 without a code change. + // + // A partial map on purpose. WPSections.normalize fills the rest in as ON, so a + // section added after today is not silently off for this SOP. + if(typeof WPSections !== 'undefined'){ + state.sections = WPSections.normalize({assets: false}); + } + // The Micron FMCS sample includes BIM/VDC — enable it so the sequence shows the // full BIM → construction flow (BIM steps first) and the Creator offers IWP/EWP. state.bimEnabled = true; diff --git a/html/wp-creation-app.js b/html/wp-creation-app.js index 75a1410..33c6ed7 100644 --- a/html/wp-creation-app.js +++ b/html/wp-creation-app.js @@ -6,6 +6,16 @@ // ── SAMPLE SOP (same shape the Configuration tool exports) ─────────────────── const SAMPLE_SOP = { meta:{tool:'Work Package Configuration', sample:true}, + // CR-016 / T5.7. This sample IS the Micron EUV configuration as far as the + // repository is concerned — it is what the standalone creator shows when there + // is no project SOP to read. Assets is off because its content duplicates the + // database Clinton's team maintains and that integration is deferred; the + // section, its data model and every value already captured stay exactly where + // they are, which is the whole point of expressing this as a toggle. + // + // Written as a partial map, not a full one: WPSections.normalize fills the rest + // in as ON, so a section added later is not silently off for this SOP. + sections:{assets:false}, project:{name:'Micron — INC Construction Work Packages', number:'26-67-008', client:'Micron Technology, Inc.', division:'Semiconductor', pm:'Nick Siegfried', cm:'K. Boyd', qm:'D. Nguyen', site:'Boise, ID — Fab'}, roles:[{role:'General Foreman',name:'M. Torres'},{role:'Superintendent',name:'K. Boyd'},{role:'Safety Manager / Lead',name:'A. Reyes'},{role:'Quality Manager',name:'D. Nguyen'},{role:'Planner',name:'L. Graver'}], governance:{ issuance:['By Sector / Area','By Discipline'], woSize:'Standard — 3–5 days (≈40–80 hrs)', woFormat:'WP##-[Sector]-[TYPE]', disciplines:['Mechanical','Electrical','Tech'], discMode:'choice', instanceSuffix:'letter', sizeHoursMax:'80' }, diff --git a/tests/sections_check.py b/tests/sections_check.py index d211cb7..34590d5 100644 --- a/tests/sections_check.py +++ b/tests/sections_check.py @@ -503,6 +503,59 @@ def run(page, base, tok, db_path): "Electrical Install" not in doc5 and "PROBE-ACUMATICA-TASK" not in doc5) set_sop(db_path, {}) + print("\nCR-016 (T5.7). Assets is off for Micron EUV, and only for it") + # The creator with no project falls back to SAMPLE_SOP, which is the Micron + # configuration as far as this repository is concerned — it is what the + # standalone page shows when there is no project SOP to read. + # + # localStorage cleared first, and this is not tidiness: activeProjectId falls + # back to ProjectData.getActiveId(), so a project left over from an earlier + # navigation sends bootSOP() down the real-project branch and the sample is + # never loaded. The probe would then report on Job A while claiming Micron. + page.eval("localStorage.clear(); true") + page.goto(base + "/wp-creation-index.html") + chk("the standalone creator boots on the Micron sample", wait_creator(page)) + settle(1.4) + page.eval(STUB) + chk("the sample really is the Micron one", + "Micron" in (page.eval("(SOP && SOP.project && SOP.project.name) || ''") or ""), + page.eval("(SOP && SOP.project && SOP.project.name) || ''")) + chk("Assets does not render in the form", + page.eval("document.getElementById('asset-card').hidden")) + chk("...and not in the section chip strip", + "Assets" not in (page.eval("(document.getElementById('section-nav')||{}).textContent||''")), + page.eval("(document.getElementById('section-nav')||{}).textContent||''")) + page.eval("renderPackage(%s)" % json.dumps(FULL_PKG)) + settle(0.7) + mdoc = page.eval("document.getElementById('pkg-doc').innerHTML") + chk("...nor in the detail view", MARKERS["assets"] not in mdoc) + chk("...nor in the PDF export, which is that document", + page.eval("document.getElementById('pkg-doc').innerHTML") == mdoc) + chk("every other section is untouched by CR-016", + all(v in mdoc for k, v in MARKERS.items() if k != "assets"), + [k for k, v in MARKERS.items() if v not in mdoc]) + chk("the section and its model are still in the codebase, not deleted", + page.eval("!!document.getElementById('asset-card')") + and page.eval("typeof pkgAssets !== 'undefined'")) + chk("...and the sample switches it off by TOGGLE, not by removing the data", + page.eval("JSON.stringify((SOP||{}).sections||{})").find("assets") >= 0, + page.eval("JSON.stringify((SOP||{}).sections||{})")) + chk("...naming only assets, so a section added later is not silently off too", + json.loads(page.eval("JSON.stringify(Object.keys((SOP||{}).sections||{})" + ".filter(k => (SOP.sections||{})[k] === false))")) == ["assets"], + page.eval("JSON.stringify((SOP||{}).sections||{})")) + + print(" another SOP enables Assets and it works") + set_sop(db_path, {}) + page.goto(base + "/wp-creation-index.html?project=projA") + chk("a different project's creator boots", wait_creator(page)) + settle(1.2) + chk("Assets renders there", not page.eval("document.getElementById('asset-card').hidden")) + page.eval("renderPackage(%s)" % json.dumps(FULL_PKG)) + settle(0.7) + chk("...and its content is in that project's document", + MARKERS["assets"] in page.eval("document.getElementById('pkg-doc').innerHTML")) + chk("no native dialog was opened anywhere in this flow", not json.loads(page.eval("JSON.stringify(window.__dialogs||[])")), page.eval("JSON.stringify(window.__dialogs||[])"))