Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading
, '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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 15 additions & 18 deletions skills/objectstack-upgrade/SKILL.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,15 +105,15 @@ Everything below is the long form of those four steps.
`--from` is the protocol major the metadata was **authored** against, not the
one installed. Three sources, in order of authority:

1. **`manifest.protocol`** in the stack config (`'16.0.0'` → `--from 16`). This
is the declared answer and the kernel checks it at load time.
1. **`manifest.engines.protocol`** in the stack config (`'16.0.0'` → `--from
16`). The declared answer, checked by the boot handshake.
2. **The last `@objectstack/spec` major the project ever installed** — read the
lockfile history (`git log -p pnpm-lock.yaml | grep -m5 '@objectstack/spec'`)
when the manifest is absent or stale.
3. **Ask.** A manifest that says 16 on a project last touched two years ago is a
claim, not a measurement. If (1) and (2) disagree, the lower one is the safe
`--from` — the chain is idempotent, so replaying a hop that has already been
applied is a no-op, while skipping a hop loses its rewrites.
claim, not a measurement. If (1) and (2) disagree, settle it — ⛔ never
default to the lower one: a default flip ([3.3](#33-validate)) stamps its
constraint onto a source already past that major.

Arriving several majors late is the designed-for case. `os migrate meta --from 10`
replays every step in order; there is no penalty for lateness and no requirement
Expand DownExpand Up@@ -296,24 +296,21 @@ The shape in a protocol-16 project:

The chain deletes the key (`field-mapping-transform-removed`) and the schema
tombstones it, so the parse error *is* the prescription: the union had five
members and **no runtime ever executed any of them**, so nothing is lost by
deleting the key — but the customer wrote it because they wanted a
transformation, and that need is real even though the key never served it.
members and **no runtime ever executed any of them**. The customer wrote it
because they wanted a transformation, and that need is real regardless.

The prescription names two live targets, and choosing between them is the
business decision:
The prescription names one live target; the rest is the business decision:

| If the intent was… | The v17 home is… |
|:--|:--|
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a flat string enum (`none`/`constant`/`map`/`split`/`join`/`lookup`) with settings in `params`, executed row by row by the REST import path. |
| multi-source, multi-stage transformation | an **ETL transformation step**. |
| per-row value shaping on an import | **Import mapping** `mapping.fieldMapping[].transform` — a string enum, settings in `params`; the REST import path runs `none`/`constant`/`map`/`split`/`join`, passes `lookup` to reference resolution, rejects `javascript` (400). |
| multi-source, multi-stage transformation | **nothing** — the L2 ETL layer retired at 17, unexecuted. Do it where it runs: warehouse ELT, a `flow`, a job. |
| nothing — the value was already correct | delete the key and record that the transformation never ran. |

That third row is not a joke and it is frequently the truth: the member never
executed, so the connector has been landing raw values for as long as it has
been running. Whether the downstream data is therefore wrong is a question only
the owner can answer, and it is exactly the kind of finding the report exists to
surface.
That third row is frequently the truth: the member never executed, so the
connector has been landing raw values for as long as it has been running.
Whether the downstream data is wrong is a question only the owner can answer —
exactly the kind of finding the report exists to surface.

<a id="decide-alone-or-ask"></a>

Expand DownExpand Up@@ -533,7 +530,7 @@ you must say which you expect:
invalid_type: `FieldMapping.transform` … was removed in @objectstack/spec
17.0.0 (ADR-0049) … Delete the key. The transform pipeline that IS
enforced is the import mapping's … Run `os migrate meta --from 16` to
rewrite it automatically.
list the mechanical edits for existing sources; apply them by hand.
expected: never
```

Expand Down
Loading