os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

Description

@os-trump

Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

What was measured

Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

kindverdict
objectparses, then FAILS the author-time rules — security-owd-unset
viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
flowparse fails — fixed by #14087
dashboardclean
skillclean
appparse fails — apps[0].navigation expects an array, the scaffold writes an object

Verbatim, the four that this card is about:

  • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
  • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
  • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
  • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

Why it is worth its own card

The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

The harness already exists

#14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

Filed unassigned, domain:* left blank per the single-producer rule.

Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
     blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
    }
    } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
    })();
    (function(){
    try {
    var __m = "github.com";
    var __re = new RegExp('^' + "github\\.com" + '
    
    Skip to content

    os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

    Description

    @os-trump

    Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

    What was measured

    Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

    kindverdict
    objectparses, then FAILS the author-time rules — security-owd-unset
    viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
    actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
    flowparse fails — fixed by #14087
    dashboardclean
    skillclean
    appparse fails — apps[0].navigation expects an array, the scaffold writes an object

    Verbatim, the four that this card is about:

    • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
    • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
    • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
    • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

    Why it is worth its own card

    The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

    The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

    The harness already exists

    #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

    Filed unassigned, domain:* left blank per the single-producer rule.

    Generated by Claude Code

    Metadata

    Metadata

    Assignees

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
      Skip to content

      os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

      Description

      @os-trump

      Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

      What was measured

      Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

      kindverdict
      objectparses, then FAILS the author-time rules — security-owd-unset
      viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
      actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
      flowparse fails — fixed by #14087
      dashboardclean
      skillclean
      appparse fails — apps[0].navigation expects an array, the scaffold writes an object

      Verbatim, the four that this card is about:

      • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
      • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
      • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
      • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

      Why it is worth its own card

      The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

      The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

      The harness already exists

      #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

      Filed unassigned, domain:* left blank per the single-producer rule.

      Generated by Claude Code

      Metadata

      Metadata

      Assignees

      Labels

      Type

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions

        , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
        Skip to content

        os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

        Description

        @os-trump

        Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

        What was measured

        Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

        kindverdict
        objectparses, then FAILS the author-time rules — security-owd-unset
        viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
        actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
        flowparse fails — fixed by #14087
        dashboardclean
        skillclean
        appparse fails — apps[0].navigation expects an array, the scaffold writes an object

        Verbatim, the four that this card is about:

        • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
        • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
        • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
        • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

        Why it is worth its own card

        The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

        The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

        The harness already exists

        #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

        Filed unassigned, domain:* left blank per the single-producer rule.

        Generated by Claude Code

        Metadata

        Metadata

        Assignees

        Labels

        Type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
          Skip to content

          os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

          Description

          @os-trump

          Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

          What was measured

          Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

          kindverdict
          objectparses, then FAILS the author-time rules — security-owd-unset
          viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
          actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
          flowparse fails — fixed by #14087
          dashboardclean
          skillclean
          appparse fails — apps[0].navigation expects an array, the scaffold writes an object

          Verbatim, the four that this card is about:

          • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
          • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
          • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
          • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

          Why it is worth its own card

          The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

          The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

          The harness already exists

          #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

          Filed unassigned, domain:* left blank per the single-producer rule.

          Generated by Claude Code

          Metadata

          Metadata

          Assignees

          Labels

          Type

          Projects

          No projects

            Milestone

            No milestone

            Relationships

            None yet

            Development

            No branches or pull requests

            Issue actions

            , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
            Skip to content

            os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

            Description

            @os-trump

            Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

            What was measured

            Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

            kindverdict
            objectparses, then FAILS the author-time rules — security-owd-unset
            viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
            actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
            flowparse fails — fixed by #14087
            dashboardclean
            skillclean
            appparse fails — apps[0].navigation expects an array, the scaffold writes an object

            Verbatim, the four that this card is about:

            • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
            • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
            • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
            • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

            Why it is worth its own card

            The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

            The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

            The harness already exists

            #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

            Filed unassigned, domain:* left blank per the single-producer rule.

            Generated by Claude Code

            Metadata

            Metadata

            Assignees

            Labels

            Type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

              Description

              @os-trump

              Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

              What was measured

              Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

              kindverdict
              objectparses, then FAILS the author-time rules — security-owd-unset
              viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
              actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
              flowparse fails — fixed by #14087
              dashboardclean
              skillclean
              appparse fails — apps[0].navigation expects an array, the scaffold writes an object

              Verbatim, the four that this card is about:

              • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
              • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
              • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
              • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

              Why it is worth its own card

              The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

              The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

              The harness already exists

              #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

              Filed unassigned, domain:* left blank per the single-producer rule.

              Generated by Claude Code

              Metadata

              Metadata

              Assignees

              Labels

              Type

              Projects

              No projects

                Milestone

                No milestone

                Relationships

                None yet

                Development

                No branches or pull requests

                Issue actions

                , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                Skip to content

                os generate scaffolds four more artifact kinds os validate refuses — object, view, action and app #14336

                Description

                @os-trump

                Found while implementing #14087 (the flow scaffold's own refusal). Triage on that card fenced a census of the OTHER generator artifacts out of it explicitly, so this is that census, filed separately rather than folded in. Unassigned.

                What was measured

                Every GENERATORS entry in packages/cli/src/commands/generate.ts was scaffolded for the name probe_thing, materialized through the same bundle-require path loadConfig uses, and put through the two steps Validate.run() performs on an authored stack — ObjectStackDefinitionSchema.safeParse after normalizeStackInput, then runAuthoringRules('validate'). Measured on origin/maind63c8a2:

                kindverdict
                objectparses, then FAILS the author-time rules — security-owd-unset
                viewparse fails — views[0].list.pageSize, plus type / objectName on the view container
                actionparse fails — type: 'custom' is not an Action type; handler is not an Action key
                flowparse fails — fixed by #14087
                dashboardclean
                skillclean
                appparse fails — apps[0].navigation expects an array, the scaffold writes an object

                Verbatim, the four that this card is about:

                • objectsecurity-owd-unset at objects[0].sharingModel: "custom object probe_thing declares no sharingModel (OWD). The runtime fails CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored decision, not an accident". This is the same rule that closed os init -t app scaffold does not compile on CLI 17.0.0 — the template's own object trips the security-owd-unset author-time rule #9666 for the os init -t app template; the os generate template was not moved with it.
                • viewUnrecognized key(s) on this list view: pageSize and Unrecognized key(s) on this view container: type, objectName, whose own guidance says the container's keys are list / form / listViews / formViews and that a single view's type must be wrapped.
                • actionInvalid option: expected one of "script"|"url"|"modal"|"flow"|"api"|"form" at actions[0].type (the scaffold writes custom), and Unrecognized key(s) on this action: handler.
                • appInvalid input: expected array, received object at apps[0].navigation (the scaffold writes { type: 'sidebar', items: [] }).

                Why it is worth its own card

                The argument #14087 makes applies to all of them without weakening: the generator is the path the docs point at, and a .strict() refusal enumerates what is allowed rather than saying where a key moved to. Four kinds are the majority of the roster.

                The object one is worth separating from the other three when this is triaged. The other three are pure shape drift; object parses fine and is refused one layer later by a rule that is asking the author for a security decision — so "make the scaffold pass" there means choosing a default OWD to emit, which is an authoring decision rather than a mechanical repair. The neighbouring precedent (#9666, os init) is where that decision was already taken once.

                The harness already exists

                #14087 landed packages/cli/test/generate-scaffold-validates.test.ts, which runs this exact measurement over the derived generator roster on every CI lap. These four are recorded there in KNOWN_UNVALIDATED_SCAFFOLDS, a shrink-only ledger with an anti-staleness assertion: a kind in the ledger must still FAIL, so whoever repairs one of these turns that test red and deletes its entry in the same PR. There is nothing to build here — repair the template, delete the line.

                Filed unassigned, domain:* left blank per the single-producer rule.

                Generated by Claude Code

                Metadata

                Metadata

                Assignees

                Labels

                Type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions