Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update AMP validator spec to 2008290323001 and improve i-amphtml-* sanitization #5356

Merged
merged 8 commits into from
Sep 12, 2020

Conversation

westonruter
Copy link
Member

@westonruter westonruter commented Sep 9, 2020

Previously #5075.

  • Run ./bin/amphtml-update.sh (lando ssh -c 'bash ./bin/amphtml-update.sh vendor/amphtml').
  • Examine diff for changelog.
  • Examine upstream diff to ensure nothing was missed.
  • Update spec generator as needed based on spec format changes.
  • Modify validating sanitizer based on changes to spec, if needed.
  • Add tests for key changes.

Changelog

  • Allow select and use elements inside of amp-mega-menu and amp-nested-menu elements.
  • Add amp-story-interactive-binary-poll, amp-story-interactive-poll, amp-story-interactive-quiz, and amp-story-interactive-results components. Allow inside of amp-story-grid-layer.
  • Add imagesizes and imagesrcset attributes to link element.
  • Add meta tags with name values for amp-story-generator-name and amp-story-generator-version'. See Add meta tags for creation tool name and version  GoogleForCreators/web-stories-wp#4332 (comment).
  • Add sticky attribute to amp-ad.
  • Add entity, entity-logo-src, and entity-url to amp-story.
  • Add animations for amp-story-cta-layer and amp-story-grid-layer: scale-fade-down and scale-fade-up.
  • Add amp-script protocol for src attribute for amp-list and adds nodom attribute to amp-script.
  • Update spec consumer to prevent img from appearing in amp-story-cta-layer, amp-story-grid-layer, and amp-story-page-attachment, since these are only relevant for transformed AMP (which the AMP Optimizer outputs after validation).

Sanitizing i-amphtml-*

Validation errors are now raised for each instance of i-amphtml-* in CSS selectors and for each instance in class attributes. When status of validation error is removed, the selector or class name is removed, but other selectors in the stylesheet and other class names are retained. Fixes #771.

Creating a Custom HTML block:

<style>
.testing::after {
    content: "PASS"; 
    color: green;
}
.i-amphtml-test::after {
    content: "FAIL";
    color: red;
}
</style>
<div title="What will come after?" data-hint="Look at the CSS!" class="testing i-amphtml-test">Test results: </div>
Before After
before after

On the frontend, before the result would be no styles at all being on the page since style[amp-custom] got removed during validation. After, however, only the invalid styles and invalid class names are removed:

Before After
image image

As for the markup emitted to the frontend, notice instead of the class attribute getting removed entirely, only the invalid i-amphtml-testing class name is removed:

Before After
<div title="What will come after?" data-hint="Look at the CSS!">Test results: </div> <div title="What will come after?" data-hint="Look at the CSS!" class="testing">Test results: </div>

Additionally, you may mark the two validation errors as Kept, at which point a third validation error will appear for the style[amp-custom] as a whole given the presence of i-amphtml-. This can be marked as Kept as well:

error-list

As expected, the invalid styles are then retained (as see by "FAIL" successfully not being sanitized):

image

Details

(
    PREV_VERSION=3aa007a;
    THIS_VERSION=2008290323001;
    git checkout $THIS_VERSION;
    git diff $PREV_VERSION...$THIS_VERSION -w -- $( git ls-files | grep '.protoascii' );
    git checkout - > /dev/null
)
3aa007a...2008290323001
diff --git a/extensions/amp-accordion/validator-amp-accordion.protoascii b/extensions/amp-accordion/validator-amp-accordion.protoascii
index 2296ddacb..ef60a92c3 100644
--- a/extensions/amp-accordion/validator-amp-accordion.protoascii
+++ b/extensions/amp-accordion/validator-amp-accordion.protoascii
@@ -16,7 +16,6 @@
 tags: {  # amp-accordion
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-accordion"
@@ -44,7 +43,6 @@ tags: {  # <amp-accordion>
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-ACCORDION"
   requires_extension: "amp-accordion"
   attrs: { name: "animate" value: "" }
@@ -68,7 +66,6 @@ tags: {  # <amp-accordion> > <section>
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SECTION"
   spec_name: "amp-accordion > section"
   descriptive_name: "amp-accordion > section"
diff --git a/extensions/amp-action-macro/validator-amp-action-macro.protoascii b/extensions/amp-action-macro/validator-amp-action-macro.protoascii
index a60ac468b..22a34c3ef 100644
--- a/extensions/amp-action-macro/validator-amp-action-macro.protoascii
+++ b/extensions/amp-action-macro/validator-amp-action-macro.protoascii
@@ -15,7 +15,6 @@
 #
 tags: {  # amp-action-macro
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-action-macro"
@@ -26,7 +25,6 @@ tags: {  # amp-action-macro
 }
 tags: {  # <amp-action-macro>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-ACTION-MACRO"
   requires_extension: "amp-action-macro"
   attrs: {
diff --git a/extensions/amp-ad/validator-amp-ad.protoascii b/extensions/amp-ad/validator-amp-ad.protoascii
index 26e0a2cff..639a4ddd9 100644
--- a/extensions/amp-ad/validator-amp-ad.protoascii
+++ b/extensions/amp-ad/validator-amp-ad.protoascii
@@ -64,6 +64,7 @@ tags: {  # <amp-ad>
   }
   attrs: { name: "template" }
   attrs: { name: "type" mandatory: true }
+  attrs: { name: "sticky" value: "" }
   attr_lists: "extended-amp-global"
   spec_url: "https://amp.dev/documentation/components/amp-ad/"
   amp_layout: {
diff --git a/extensions/amp-analytics/validator-amp-analytics.protoascii b/extensions/amp-analytics/validator-amp-analytics.protoascii
index 29b460e93..59b3042ef 100644
--- a/extensions/amp-analytics/validator-amp-analytics.protoascii
+++ b/extensions/amp-analytics/validator-amp-analytics.protoascii
@@ -18,7 +18,6 @@
 tags: {  # amp-analytics
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-analytics"
@@ -32,7 +31,6 @@ tags: {  # amp-analytics
 tags: {  # amp-analytics (json)
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-analytics extension .json script"
   descriptive_name: "amp-analytics extension .json script"
@@ -56,7 +54,6 @@ tags: {  # amp-analytics (json)
 tags: {  # <amp-analytics>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-ANALYTICS"
   requires_extension: "amp-analytics"
   attrs: {
diff --git a/extensions/amp-anim/validator-amp-anim.protoascii b/extensions/amp-anim/validator-amp-anim.protoascii
index 7e9a569c7..39aa3e94f 100644
--- a/extensions/amp-anim/validator-amp-anim.protoascii
+++ b/extensions/amp-anim/validator-amp-anim.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-anim
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-anim"
@@ -42,7 +41,6 @@ tags: {  # amp-anim
 tags: {  # <amp-anim>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-ANIM"
   requires_extension: "amp-anim"
   attrs: { name: "alt" }
diff --git a/extensions/amp-animation/validator-amp-animation.protoascii b/extensions/amp-animation/validator-amp-animation.protoascii
index 477695c94..0fce91192 100644
--- a/extensions/amp-animation/validator-amp-animation.protoascii
+++ b/extensions/amp-animation/validator-amp-animation.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-animation
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-animation"
@@ -29,7 +28,6 @@ tags: {  # amp-animation
 tags: {  # <amp-animation> (json)
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-animation extension .json script"
   mandatory_parent: "AMP-ANIMATION"
@@ -52,7 +50,6 @@ tags: {  # <amp-animation> (json)
 tags: {  # <amp-animation>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-ANIMATION"
   requires_extension: "amp-animation"
   requires: "amp-animation extension .json script"
diff --git a/extensions/amp-autocomplete/validator-amp-autocomplete.protoascii b/extensions/amp-autocomplete/validator-amp-autocomplete.protoascii
index d40824239..4f4cbdcfb 100644
--- a/extensions/amp-autocomplete/validator-amp-autocomplete.protoascii
+++ b/extensions/amp-autocomplete/validator-amp-autocomplete.protoascii
@@ -105,7 +105,6 @@ tags: {  # <amp-autocomplete>
   attrs: { name: "highlight-user-entry" }
   attrs: { name: "inline" }
   attrs: { name: "items" }
-  attrs: { name: "max-entries" }
   attrs: { name: "max-items" }
   attrs: { name: "min-characters" }
   attrs: {
diff --git a/extensions/amp-base-carousel/validator-amp-base-carousel.protoascii b/extensions/amp-base-carousel/validator-amp-base-carousel.protoascii
index e7132e6bc..70f94e45f 100644
--- a/extensions/amp-base-carousel/validator-amp-base-carousel.protoascii
+++ b/extensions/amp-base-carousel/validator-amp-base-carousel.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-base-carousel
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-base-carousel"
@@ -116,7 +115,6 @@ attr_lists: {
 
 tags: {  # <amp-base-carousel>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-BASE-CAROUSEL"
   requires_extension: "amp-base-carousel"
   attr_lists: "amp-base-carousel-common"
@@ -135,7 +133,6 @@ tags: {  # <amp-base-carousel>
 
 tags: {  # <amp-base-carousel lightbox>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-BASE-CAROUSEL"
   spec_name: "AMP-BASE-CAROUSEL [lightbox]"
   requires_extension: "amp-base-carousel"
@@ -166,7 +163,6 @@ tags: {  # <amp-base-carousel lightbox>
 
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name: "AMP-BASE-CAROUSEL lightbox [lightbox-exclude]"
   attrs: {
@@ -176,7 +172,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name: "AMP-BASE-CAROUSEL lightbox [child]"
   attrs: {
diff --git a/extensions/amp-bind/validator-amp-bind.protoascii b/extensions/amp-bind/validator-amp-bind.protoascii
index 36e16935f..2e0628779 100644
--- a/extensions/amp-bind/validator-amp-bind.protoascii
+++ b/extensions/amp-bind/validator-amp-bind.protoascii
@@ -16,7 +16,6 @@
 tags: {  # amp-bind
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-bind"
@@ -48,7 +47,6 @@ tags: {  # <amp-state> (json)
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-bind extension .json script"
   requires_extension: "amp-bind"
@@ -115,41 +113,8 @@ tags: {  # <amp-state>
   }
   spec_url: "https://amp.dev/documentation/components/amp-bind/"
 }
-# ACTIONS <amp-state> with POST identity
-tags: { # <amp-state>
-  html_format: ACTIONS
-  tag_name: "AMP-STATE"
-  spec_name: "AMP-STATE (ACTIONS)"
-  requires_extension: "amp-bind"
-  attrs: {
-    name: "credentials"
-  }
-  attrs: {
-    name: "crossorigin"
-    value: "amp-viewer-auth-token-via-post"
-  }
-  attrs: {
-    name: "overridable"
-  }
-  attrs: {
-    name: "src"
-    value_url: {
-      protocol: "https"
-      allow_relative: true  # Will be set to false at a future date.
-    }
-    disallowed_value_regex: "__amp_source_origin"
-  }
-  attr_lists: "mandatory-id-attr"
-  # <amp-bind>
-  attrs: { name: "[src]" }
-  child_tags: {
-    first_child_tag_name_oneof: "SCRIPT"
-  }
-  spec_url: "https://amp.dev/documentation/components/amp-bind/"
-}
 tags: {  # <amp-bind-macro>
   html_format: AMP
-  html_format: ACTIONS
   html_format: AMP4EMAIL
   tag_name: "AMP-BIND-MACRO"
   requires_extension: "amp-bind"
diff --git a/extensions/amp-bodymovin-animation/validator-amp-bodymovin-animation.protoascii b/extensions/amp-bodymovin-animation/validator-amp-bodymovin-animation.protoascii
index a00b1ca88..c7c93fec0 100644
--- a/extensions/amp-bodymovin-animation/validator-amp-bodymovin-animation.protoascii
+++ b/extensions/amp-bodymovin-animation/validator-amp-bodymovin-animation.protoascii
@@ -31,9 +31,7 @@ tags: {  # <amp-bodymovin-animation>
 
   attrs: {
     name: "loop"
-    value_casei: "false"
-    value_casei: "number"
-    value_casei: "true"
+    value_regex_casei: "[1-9][0-9]*|false|true"
   }
   attrs: {
     name: "noautoplay"
diff --git a/extensions/amp-carousel/validator-amp-carousel.protoascii b/extensions/amp-carousel/validator-amp-carousel.protoascii
index 0549b2bbf..897aad176 100644
--- a/extensions/amp-carousel/validator-amp-carousel.protoascii
+++ b/extensions/amp-carousel/validator-amp-carousel.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-carousel
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-carousel"
@@ -86,7 +85,6 @@ tags: {  # <amp-carousel>
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-CAROUSEL"
   spec_name: "AMP-CAROUSEL"
   requires_extension: "amp-carousel"
diff --git a/extensions/amp-experiment/validator-amp-experiment.protoascii b/extensions/amp-experiment/validator-amp-experiment.protoascii
index d84b5ec70..7db7c9c47 100644
--- a/extensions/amp-experiment/validator-amp-experiment.protoascii
+++ b/extensions/amp-experiment/validator-amp-experiment.protoascii
@@ -17,7 +17,6 @@
 # Specific script tags for custom elements and runtime imports.
 tags: {  # amp-experiment
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-experiment"
@@ -31,7 +30,6 @@ tags: {  # amp-experiment
 }
 tags: {  # amp-experiment (json)
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-experiment extension .json script"
   mandatory_parent: "AMP-EXPERIMENT"
@@ -54,7 +52,6 @@ tags: {  # amp-experiment (json)
 }
 tags: {  # <amp-experiment>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-EXPERIMENT"
   requires_extension: "amp-experiment"
   unique: true
diff --git a/extensions/amp-fit-text/validator-amp-fit-text.protoascii b/extensions/amp-fit-text/validator-amp-fit-text.protoascii
index 203e1b554..f4b0f1219 100644
--- a/extensions/amp-fit-text/validator-amp-fit-text.protoascii
+++ b/extensions/amp-fit-text/validator-amp-fit-text.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-fit-text
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-fit-text"
@@ -45,7 +44,6 @@ tags: {  # <amp-fit-text>
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-FIT-TEXT"
   requires_extension: "amp-fit-text"
   attrs: { name: "max-font-size" }
diff --git a/extensions/amp-font/validator-amp-font.protoascii b/extensions/amp-font/validator-amp-font.protoascii
index 7b375a3e3..a77474651 100644
--- a/extensions/amp-font/validator-amp-font.protoascii
+++ b/extensions/amp-font/validator-amp-font.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-font
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-font"
@@ -31,7 +30,6 @@ tags: {  # amp-font
 tags: {  # <amp-font>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-FONT"
   requires_extension: "amp-font"
   attrs: {
diff --git a/extensions/amp-form/validator-amp-form.protoascii b/extensions/amp-form/validator-amp-form.protoascii
index 3c6558b1a..a34d05681 100644
--- a/extensions/amp-form/validator-amp-form.protoascii
+++ b/extensions/amp-form/validator-amp-form.protoascii
@@ -18,7 +18,6 @@ tags: {  # amp-form
   # under section "4.10 Forms"
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-form"
diff --git a/extensions/amp-fx-collection/validator-amp-fx-collection.protoascii b/extensions/amp-fx-collection/validator-amp-fx-collection.protoascii
index 6b93d762e..074bc0365 100644
--- a/extensions/amp-fx-collection/validator-amp-fx-collection.protoascii
+++ b/extensions/amp-fx-collection/validator-amp-fx-collection.protoascii
@@ -17,7 +17,6 @@ tags: {  # amp-fx-collection
   # Accepted amp-fx-collection attributes can be found in
   # validator-main.protoascii
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-fx-collection"
diff --git a/extensions/amp-image-lightbox/validator-amp-image-lightbox.protoascii b/extensions/amp-image-lightbox/validator-amp-image-lightbox.protoascii
index 43c62d817..3befadb76 100644
--- a/extensions/amp-image-lightbox/validator-amp-image-lightbox.protoascii
+++ b/extensions/amp-image-lightbox/validator-amp-image-lightbox.protoascii
@@ -15,7 +15,6 @@
 #
 tags: {  # amp-image-lightbox
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-image-lightbox"
diff --git a/extensions/amp-lightbox/validator-amp-lightbox.protoascii b/extensions/amp-lightbox/validator-amp-lightbox.protoascii
index 308668f21..e99a3941e 100644
--- a/extensions/amp-lightbox/validator-amp-lightbox.protoascii
+++ b/extensions/amp-lightbox/validator-amp-lightbox.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-lightbox
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-lightbox"
@@ -54,7 +53,6 @@ tags: {  # amp-lightbox
 tags: {  # <amp-lightbox>
   html_format: AMP
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-LIGHTBOX"
   requires_extension: "amp-lightbox"
   attrs: {
diff --git a/extensions/amp-list/validator-amp-list.protoascii b/extensions/amp-list/validator-amp-list.protoascii
index 098ee8629..de73fe62a 100644
--- a/extensions/amp-list/validator-amp-list.protoascii
+++ b/extensions/amp-list/validator-amp-list.protoascii
@@ -36,17 +36,6 @@ tags: {  # amp-list
   }
   attr_lists: "common-extension-attrs"
 }
-tags: {  # amp-list
-  html_format: ACTIONS
-  tag_name: "SCRIPT"
-  spec_name: "SCRIPT[custom-element=amp-list] (ACTIONS)"
-  extension_spec: {
-    name: "amp-list"
-    version: "0.1"
-    version: "latest"
-  }
-  attr_lists: "common-extension-attrs"
-}
 tags: {  # <amp-list> with mandatory src and/or [src] attr
   html_format: AMP
   tag_name: "AMP-LIST"
@@ -92,13 +81,13 @@ tags: {  # <amp-list> with mandatory src and/or [src] attr
     value: "fetch"
   }
   attrs: { name: "single-item" }
-  attrs: { name: "xssi-prefix" }
   attrs: {
     name: "src"
     mandatory_anyof: "['src','[src]','data-amp-bind-src']"
     value_url: {
       protocol: "https"
       protocol: "amp-state"
+      protocol: "amp-script"
       allow_relative: true  # Will be set to false at a future date.
     }
     disallowed_value_regex: "__amp_source_origin"
@@ -107,6 +96,7 @@ tags: {  # <amp-list> with mandatory src and/or [src] attr
     name: "template"
     value_oneof_set: TEMPLATE_IDS
   }
+  attrs: { name: "xssi-prefix" }
   # <amp-bind>
   attrs: {
     name: "[is-layout-container]"
@@ -129,7 +119,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "AMP-LIST DIV [fetch-error]"
   mandatory_ancestor: "AMP-LIST"
@@ -142,7 +131,6 @@ tags: {
 
 tags: { # amp-list-load-more
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-LIST-LOAD-MORE"
   requires_extension: "amp-list"
   mandatory_parent: "AMP-LIST"
@@ -171,7 +159,6 @@ tags: { # amp-list-load-more
 # The button element variant allowed in amp-list-load-more.
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   requires_extension: "amp-list"
   tag_name: "BUTTON"
   spec_name: "amp-list-load-more button[load-more-clickable]"
@@ -236,6 +223,7 @@ tags: {  # <amp-list>
     name: "template"
     value_oneof_set: TEMPLATE_IDS
   }
+  attrs: { name: "xssi-prefix" }
   # <amp-bind>
   attrs: {
     name: "[is-layout-container]"
@@ -251,68 +239,3 @@ tags: {  # <amp-list>
     supported_layouts: RESPONSIVE
   }
 }
-# ACTIONS <amp-list> with POST identity token
-tags: {  # <amp-list>
-  html_format: ACTIONS
-  tag_name: "AMP-LIST"
-  spec_name: "AMP-LIST (ACTIONS)"
-  requires_extension: "amp-list"
-  attrs: {
-    name: "auto-resize"
-    value: ""
-    deprecation: "replacement-to-be-determined-at-a-later-date"
-    deprecation_url: "https://github.com/ampproject/amphtml/issues/18849"
-  }
-  attrs: {
-    name: "binding"
-    value: "always"
-    value: "no"
-    value: "refresh"
-  }
-  attrs: { name: "credentials" }
-  attrs: {
-    name: "crossorigin"
-    value: "amp-viewer-auth-token-via-post"
-  }
-  attrs: {
-    name: "diffable"
-    value: ""
-  }
-  attrs: { name: "items" }
-  attrs: { name: "max-items" }
-  attrs: {
-    name: "reset-on-refresh"
-    value: ""
-    value: "always"
-    value: "fetch"
-  }
-  attrs: { name: "single-item" }
-  attrs: {
-    name: "src"
-    mandatory_anyof: "['src','[src]','data-amp-bind-src']"
-    value_url: {
-      protocol: "https"
-      allow_relative: true
-    }
-    disallowed_value_regex: "__amp_source_origin"
-  }
-  attrs: { name: "template" }
-  # <amp-bind>
-  attrs: {
-    name: "[src]"
-    mandatory_anyof: "['src','[src]','data-amp-bind-src']"
-  }
-  attrs: {
-    name: "[state]"
-    deprecation: "[src]"
-  }
-  attr_lists: "extended-amp-global"
-  amp_layout: {
-    supported_layouts: FILL
-    supported_layouts: FIXED
-    supported_layouts: FIXED_HEIGHT
-    supported_layouts: FLEX_ITEM
-    supported_layouts: NODISPLAY
-    supported_layouts: RESPONSIVE
-  }
-}
diff --git a/extensions/amp-live-list/validator-amp-live-list.protoascii b/extensions/amp-live-list/validator-amp-live-list.protoascii
index 350fa7db4..531fc2183 100644
--- a/extensions/amp-live-list/validator-amp-live-list.protoascii
+++ b/extensions/amp-live-list/validator-amp-live-list.protoascii
@@ -15,7 +15,6 @@
 #
 tags: {  # amp-live-list
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   mandatory_parent: "HEAD"
   unique_warning: true
@@ -29,7 +28,6 @@ tags: {  # amp-live-list
 }
 tags: {  # <amp-live-list>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-LIVE-LIST"
   requires_extension: "amp-live-list"
   attrs: {
@@ -71,7 +69,6 @@ tags: {  # <amp-live-list>
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name : "AMP-LIVE-LIST [update]"
   descriptive_name : "amp-live-list [update]"
@@ -83,7 +80,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name: "AMP-LIVE-LIST [items]"
   descriptive_name : "amp-live-list [items]"
@@ -98,7 +94,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name : "AMP-LIVE-LIST [pagination]"
   descriptive_name : "amp-live-list [pagination]"
@@ -110,7 +105,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name : "AMP-LIVE-LIST [items] item"
   descriptive_name : "amp-live-list [items] item"
diff --git a/extensions/amp-mega-menu/validator-amp-mega-menu.protoascii b/extensions/amp-mega-menu/validator-amp-mega-menu.protoascii
index d2cc8f3b5..0aba0d19b 100644
--- a/extensions/amp-mega-menu/validator-amp-mega-menu.protoascii
+++ b/extensions/amp-mega-menu/validator-amp-mega-menu.protoascii
@@ -203,6 +203,7 @@ descendant_tag_list {
   tag: "P"
   tag: "PATH"
   tag: "SECTION"
+  tag: "SELECT"
   tag: "SPAN"
   tag: "STRIKE"
   tag: "STRONG"
@@ -219,4 +220,5 @@ descendant_tag_list {
   tag: "TR"
   tag: "U"
   tag: "UL"
+  tag: "USE"
 }
diff --git a/extensions/amp-mustache/validator-amp-mustache.protoascii b/extensions/amp-mustache/validator-amp-mustache.protoascii
index 470835b36..c64acbe80 100644
--- a/extensions/amp-mustache/validator-amp-mustache.protoascii
+++ b/extensions/amp-mustache/validator-amp-mustache.protoascii
@@ -36,9 +36,8 @@ tags: {  # amp-mustache
 }
 tags: {  # amp-mustache
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
-  spec_name: "SCRIPT[custom-template=amp-mustache] (AMP4ADS/ACTIONS)"
+  spec_name: "SCRIPT[custom-template=amp-mustache] (AMP4ADS)"
   extension_spec: {
     name: "amp-mustache"
     extension_type: CUSTOM_TEMPLATE
@@ -67,7 +66,6 @@ tags: {  # amp-mustache
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "SCRIPT type=text/plain"
   disallowed_ancestor: "TEMPLATE"
@@ -389,7 +387,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TEMPLATE"
   mandatory_ancestor: "BODY"
   # <template> tags may not be nested inside other <template> tags.
diff --git a/extensions/amp-nested-menu/validator-amp-nested-menu.protoascii b/extensions/amp-nested-menu/validator-amp-nested-menu.protoascii
index d1a438034..7ef5f39b2 100644
--- a/extensions/amp-nested-menu/validator-amp-nested-menu.protoascii
+++ b/extensions/amp-nested-menu/validator-amp-nested-menu.protoascii
@@ -156,6 +156,7 @@ descendant_tag_list {
   tag: "P"
   tag: "PATH"
   tag: "SECTION"
+  tag: "SELECT"
   tag: "SPAN"
   tag: "STRIKE"
   tag: "STRONG"
@@ -172,4 +173,5 @@ descendant_tag_list {
   tag: "TR"
   tag: "U"
   tag: "UL"
+  tag: "USE"
 }
diff --git a/extensions/amp-orientation-observer/validator-amp-orientation-observer.protoascii b/extensions/amp-orientation-observer/validator-amp-orientation-observer.protoascii
index ff0ffcd0a..f4966c17e 100644
--- a/extensions/amp-orientation-observer/validator-amp-orientation-observer.protoascii
+++ b/extensions/amp-orientation-observer/validator-amp-orientation-observer.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-orientation-observer
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-orientation-observer"
@@ -27,7 +26,6 @@ tags: {  # amp-orientation-observer
 }
 tags: {  # <amp-orientation-observer>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-ORIENTATION-OBSERVER"
   requires_extension: "amp-orientation-observer"
   attr_lists: "extended-amp-global"
diff --git a/extensions/amp-pan-zoom/validator-amp-pan-zoom.protoascii b/extensions/amp-pan-zoom/validator-amp-pan-zoom.protoascii
index 6b4cfaa41..085c09ba7 100644
--- a/extensions/amp-pan-zoom/validator-amp-pan-zoom.protoascii
+++ b/extensions/amp-pan-zoom/validator-amp-pan-zoom.protoascii
@@ -15,7 +15,6 @@
 #
 tags: {  # amp-pan-zoom
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-pan-zoom"
@@ -26,7 +25,6 @@ tags: {  # amp-pan-zoom
 }
 tags: {  # <amp-pan-zoom>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-PAN-ZOOM"
   requires_extension: "amp-pan-zoom"
   attrs: {
diff --git a/extensions/amp-position-observer/validator-amp-position-observer.protoascii b/extensions/amp-position-observer/validator-amp-position-observer.protoascii
index bbc25147c..773e3e185 100644
--- a/extensions/amp-position-observer/validator-amp-position-observer.protoascii
+++ b/extensions/amp-position-observer/validator-amp-position-observer.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-position-observer
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-position-observer"
@@ -29,7 +28,6 @@ tags: {  # amp-position-observer
 tags: {  # <amp-position-observer>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-POSITION-OBSERVER"
   requires_extension: "amp-position-observer"
   attrs: {
diff --git a/extensions/amp-script/validator-amp-script.protoascii b/extensions/amp-script/validator-amp-script.protoascii
index e168ea8d3..d5294f3fc 100644
--- a/extensions/amp-script/validator-amp-script.protoascii
+++ b/extensions/amp-script/validator-amp-script.protoascii
@@ -184,6 +184,12 @@ tags: {  # <amp-script>
   tag_name: "AMP-SCRIPT"
   disallowed_ancestor: "AMP-SCRIPT"
   requires_extension: "amp-script"
+  attrs: {
+    # This attribute should always be invalid. See https://github.com/ampproject/amphtml/pull/27076
+    name: "data-ampdevmode"
+    value: "false"
+    disallowed_value_regex: "false"
+  }
   attrs: {
     name: "max-age"
     value_regex: "[0-9]+"
@@ -193,10 +199,8 @@ tags: {  # <amp-script>
     }
   }
   attrs: {
-    # This attribute should always be invalid. See https://github.com/ampproject/amphtml/pull/27076
-    name: "data-ampdevmode"
-    value: "false"
-    disallowed_value_regex: "false"
+    name: "nodom"
+    value: ""
   }
   attrs: { name: "sandbox" }
   attrs: {
diff --git a/extensions/amp-selector/validator-amp-selector.protoascii b/extensions/amp-selector/validator-amp-selector.protoascii
index 7f00ca210..fbb79c094 100644
--- a/extensions/amp-selector/validator-amp-selector.protoascii
+++ b/extensions/amp-selector/validator-amp-selector.protoascii
@@ -16,7 +16,6 @@
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-selector"
@@ -43,7 +42,6 @@ tags: {  # <amp-selector> for AMP (autoplay attribute allowed)
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-SELECTOR"
   disallowed_ancestor: "AMP-SELECTOR"
   requires_extension: "amp-selector"
@@ -97,7 +95,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name: "AMP-SELECTOR option"
   attrs: {
@@ -118,7 +115,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "$REFERENCE_POINT"
   spec_name: "AMP-SELECTOR child"
   reference_points: {
diff --git a/extensions/amp-sidebar/validator-amp-sidebar.protoascii b/extensions/amp-sidebar/validator-amp-sidebar.protoascii
index 18125e475..fe5416ce1 100644
--- a/extensions/amp-sidebar/validator-amp-sidebar.protoascii
+++ b/extensions/amp-sidebar/validator-amp-sidebar.protoascii
@@ -15,7 +15,6 @@
 #
 tags: {  # amp-sidebar
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-sidebar"
@@ -39,7 +38,6 @@ tags: {  # amp-sidebar
 }
 tags: {  # <amp-sidebar> not in amp-story or email
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-SIDEBAR"
   spec_name: "amp-sidebar"
   # There is an alternate spec for amp-sidebar in amp-story.
@@ -90,7 +88,6 @@ tags: { # <amp-sidebar> in amp-story
 tags: {  # amp-sidebar > nav
   html_format: AMP
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "NAV"
   spec_name: "amp-sidebar > nav"
   mandatory_parent: "AMP-SIDEBAR"
diff --git a/extensions/amp-story-interactive/validator-amp-story-interactive.protoascii b/extensions/amp-story-interactive/validator-amp-story-interactive.protoascii
new file mode 100644
index 000000000..7a5eab5e6
--- /dev/null
+++ b/extensions/amp-story-interactive/validator-amp-story-interactive.protoascii
@@ -0,0 +1,218 @@
+#
+# Copyright 2020 The AMP HTML Authors. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License")
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS-IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the license.
+#
+
+tags: {  # amp-story-interactive
+  html_format: AMP
+  tag_name: "SCRIPT"
+  extension_spec: {
+    name: "amp-story-interactive"
+    version: "1.0"
+    version: "latest"
+  }
+  attr_lists: "common-extension-attrs"
+}
+tags: {  # <amp-story-interactive-quiz>
+  html_format: AMP
+  tag_name: "AMP-STORY-INTERACTIVE-QUIZ"
+  requires_extension: "amp-story-interactive"
+  mandatory_ancestor: "AMP-STORY-GRID-LAYER"
+  attr_lists: 'interactive-options-text-attrs'
+  attr_lists: 'interactive-options-confetti-attrs'
+  attr_lists: 'interactive-shared-configs-attrs'
+  attrs: {
+    name: 'option-1-correct'
+    mandatory_oneof: "['option-1-correct', 'option-2-correct', 'option-3-correct', 'option-4-correct']"
+  }
+  attrs: {
+    name: 'option-2-correct'
+    mandatory_oneof: "['option-1-correct', 'option-2-correct', 'option-3-correct', 'option-4-correct']"
+  }
+  attrs: {
+    name: 'option-3-correct'
+    mandatory_oneof: "['option-1-correct', 'option-2-correct', 'option-3-correct', 'option-4-correct']"
+  }
+  attrs: {
+    name: 'option-4-correct'
+    mandatory_oneof: "['option-1-correct', 'option-2-correct', 'option-3-correct', 'option-4-correct']"
+  }
+}
+tags: {  # <amp-story-interactive-poll>
+  html_format: AMP
+  tag_name: "AMP-STORY-INTERACTIVE-POLL"
+  requires_extension: "amp-story-interactive"
+  mandatory_ancestor: "AMP-STORY-GRID-LAYER"
+  attr_lists: 'interactive-options-text-attrs'
+  attr_lists: 'interactive-options-confetti-attrs'
+  attr_lists: 'interactive-options-results-category-attrs'
+  attr_lists: 'interactive-shared-configs-attrs'
+}
+tags: {  # <amp-story-interactive-binary-poll>
+  html_format: AMP
+  tag_name: "AMP-STORY-INTERACTIVE-BINARY-POLL"
+  requires_extension: "amp-story-interactive"
+  mandatory_ancestor: "AMP-STORY-GRID-LAYER"
+  attr_lists: 'interactive-shared-configs-attrs'
+  attrs: {
+    name: 'option-1-text'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-2-text'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-1-confetti'
+  }
+  attrs: {
+    name: 'option-2-confetti'
+  }
+}
+tags: {  # <amp-story-interactive-results>
+  html_format: AMP
+  tag_name: "AMP-STORY-INTERACTIVE-RESULTS"
+  requires_extension: "amp-story-interactive"
+  mandatory_ancestor: "AMP-STORY-GRID-LAYER"
+  attrs: {
+    name: 'option-1-results-category'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-2-results-category'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-3-results-category'
+  }
+  attrs: {
+    name: 'option-4-results-category'
+  }
+  attrs: {
+    name: 'option-1-image'
+  }
+  attrs: {
+    name: 'option-2-image'
+  }
+  attrs: {
+    name: 'option-3-image'
+  }
+  attrs: {
+    name: 'option-4-image'
+  }
+  attrs: {
+    name: 'option-1-text'
+  }
+  attrs: {
+    name: 'option-2-text'
+  }
+  attrs: {
+    name: 'option-3-text'
+  }
+  attrs: {
+    name: 'option-4-text'
+  }
+  attrs: {
+    name: 'prompt-text'
+  }
+  attrs: {
+    name: 'theme'
+    value: 'light'
+    value: 'dark'
+  }
+}
+
+attr_lists: {
+  name: 'interactive-shared-configs-attrs'
+  attrs: {
+    name: 'id'
+    mandatory: true
+  }
+  attrs: {
+    name: 'prompt-text'
+  }
+  attrs: {
+    name: 'endpoint'
+    mandatory: true
+    value_url: {
+      protocol: 'https'
+      allow_relative: false
+      allow_empty: false
+    }
+  }
+  attrs: {
+    name: 'theme'
+    value: 'light'
+    value: 'dark'
+  }
+  attrs: {
+    name: 'chip-style'
+    value: 'shadow'
+    value: 'flat'
+    value: 'transparent'
+  }
+  attrs: {
+    name: 'prompt-size'
+    value: 'small'
+    value: 'medium'
+    value: 'large'
+  }
+}
+attr_lists: {
+  name: 'interactive-options-text-attrs'
+  attrs: {
+    name: 'option-1-text'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-2-text'
+    mandatory: true
+  }
+  attrs: {
+    name: 'option-3-text'
+  }
+  attrs: {
+    name: 'option-4-text'
+  }
+}
+attr_lists: {
+  name: 'interactive-options-confetti-attrs'
+  attrs: {
+    name: 'option-1-confetti'
+  }
+  attrs: {
+    name: 'option-2-confetti'
+  }
+  attrs: {
+    name: 'option-3-confetti'
+  }
+  attrs: {
+    name: 'option-4-confetti'
+  }
+}
+attr_lists: {
+  name: 'interactive-options-results-category-attrs'
+  attrs: {
+    name: 'option-1-results-category'
+  }
+  attrs: {
+    name: 'option-2-results-category'
+  }
+  attrs: {
+    name: 'option-3-results-category'
+  }
+  attrs: {
+    name: 'option-4-results-category'
+  }
+}
diff --git a/extensions/amp-story/validator-amp-story.protoascii b/extensions/amp-story/validator-amp-story.protoascii
index f9e494e0a..5b11c2eed 100644
--- a/extensions/amp-story/validator-amp-story.protoascii
+++ b/extensions/amp-story/validator-amp-story.protoascii
@@ -41,6 +41,23 @@ tags: {  # <amp-story>
       protocol: "https"
     }
   }
+  attrs: {
+    name: "entity"
+  }
+  attrs: {
+    name: "entity-logo-src"
+    value_url: {
+      protocol: "http"
+      protocol: "https"
+    }
+  }
+  attrs: {
+    name: "entity-url"
+    value_url: {
+      protocol: "http"
+      protocol: "https"
+    }
+  }
   attrs: {
     name: "poster-landscape-src"
     value_url: {
@@ -219,6 +236,8 @@ tags: {
     value: "pulse"
     value: "rotate-in-left"
     value: "rotate-in-right"
+    value: "scale-fade-down"
+    value: "scale-fade-up"
     value: "twirl-in"
     value: "whoosh-in-left"
     value: "whoosh-in-right"
@@ -300,6 +319,8 @@ tags: {
     value: "pulse"
     value: "rotate-in-left"
     value: "rotate-in-right"
+    value: "scale-fade-down"
+    value: "scale-fade-up"
     value: "twirl-in"
     value: "whoosh-in-left"
     value: "whoosh-in-right"
@@ -438,7 +459,6 @@ tags: {  # <amp-story-cta-layer>
 }
 tags: {  # amp-experiment (json)
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-experiment story extension .json script"
   mandatory_parent: "AMP-EXPERIMENT"
@@ -478,6 +498,8 @@ tags: {
     value: "pulse"
     value: "rotate-in-left"
     value: "rotate-in-right"
+    value: "scale-fade-down"
+    value: "scale-fade-up"
     value: "twirl-in"
     value: "whoosh-in-left"
     value: "whoosh-in-right"
@@ -564,6 +586,7 @@ descendant_tag_list: {
   tag: "HKERN"
   tag: "HR"
   tag: "I"
+  tag: "IMG"  # Only allowed when document is transformed AMP
   tag: "I-AMPHTML-SIZER"  # Only allowed when document is transformed AMP
   tag: "IMAGE"
   tag: "INS"
@@ -640,6 +663,10 @@ descendant_tag_list: {
   tag: "AMP-PIXEL"
   tag: "AMP-STATE"
   tag: "AMP-STORY-360"
+  tag: "AMP-STORY-INTERACTIVE-BINARY-POLL"
+  tag: "AMP-STORY-INTERACTIVE-POLL"
+  tag: "AMP-STORY-INTERACTIVE-QUIZ"
+  tag: "AMP-STORY-INTERACTIVE-RESULTS"
   tag: "AMP-TIMEAGO"
   tag: "AMP-TWITTER"
   tag: "AMP-VIDEO"
@@ -694,6 +721,7 @@ descendant_tag_list: {
   tag: "HR"
   tag: "I"
   tag: "IMAGE"
+  tag: "IMG"  # Only allowed when document is transformed AMP
   tag: "I-AMPHTML-SIZER"  # Only allowed when document is transformed AMP
   tag: "INS"
   tag: "KBD"
@@ -847,6 +875,40 @@ tags: {  # <amp-story-animation>
     supported_layouts: NODISPLAY
   }
 }
+# AMP Story metadata, name=amp-story-generator-name
+tags: {
+  html_format: AMP
+  tag_name: "META"
+  spec_name: "meta name=amp-story-generator-name"
+  mandatory_parent: "HEAD"
+  unique: true
+  attrs: {
+    name: "content"
+    mandatory: true
+  }
+  attrs: {
+    name: "name"
+    mandatory: true
+    value_casei: "amp-story-generator-name"
+  }
+}
+# AMP Story metadata, name=amp-story-generator-version
+tags: {
+  html_format: AMP
+  tag_name: "META"
+  spec_name: "meta name=amp-story-generator-version"
+  mandatory_parent: "HEAD"
+  unique: true
+  attrs: {
+    name: "content"
+    mandatory: true
+  }
+  attrs: {
+    name: "name"
+    mandatory: true
+    value_casei: "amp-story-generator-version"
+  }
+}
 descendant_tag_list {
   # Allowlisting as many components as possible, unless they could result in a
   # bad UX (ie: modal in a modal with amp-lightbox), or potential security
@@ -969,6 +1031,7 @@ descendant_tag_list {
   tag: "HR"
   tag: "I"
   tag: "IMAGE"
+  tag: "IMG"  # Only allowed when document is transformed AMP
   tag: "I-AMPHTML-SIZER"  # Only allowed when document is transformed AMP
   tag: "INS"
   tag: "KBD"
diff --git a/extensions/amp-timeago/validator-amp-timeago.protoascii b/extensions/amp-timeago/validator-amp-timeago.protoascii
index e9cc76e30..fad65eda8 100644
--- a/extensions/amp-timeago/validator-amp-timeago.protoascii
+++ b/extensions/amp-timeago/validator-amp-timeago.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-timeago
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-timeago"
@@ -39,7 +38,6 @@ tags: {  # amp-timeago
 tags: {  # <amp-timeago>
   html_format: AMP
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-TIMEAGO"
   requires_extension: "amp-timeago"
   attrs: {
diff --git a/extensions/amp-video/validator-amp-video.protoascii b/extensions/amp-video/validator-amp-video.protoascii
index fea8c62c8..2b0154991 100644
--- a/extensions/amp-video/validator-amp-video.protoascii
+++ b/extensions/amp-video/validator-amp-video.protoascii
@@ -17,7 +17,6 @@
 tags: {  # amp-video
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   # Typically the extension_spec takes care of this, but we have
   # a unique situation where we need to refer to this earlier in
@@ -109,7 +108,6 @@ attr_lists: {
 tags: {  # <amp-video> not in amp-story.
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-VIDEO"
   # There is an alternate spec for amp-video in amp-story.
   disallowed_ancestor: "AMP-STORY"
@@ -135,7 +133,6 @@ tags: {  # <amp-video> not in amp-story.
 tags: {  # <amp-video> in amp-story-page-attachment (same rules as regular AMPHTML).
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-VIDEO"
   spec_name: "amp-story >> amp-story-page-attachment >> amp-video"
   mandatory_ancestor: "AMP-STORY-PAGE-ATTACHMENT"
diff --git a/extensions/amp-yotpo/validator-amp-yotpo.protoascii b/extensions/amp-yotpo/validator-amp-yotpo.protoascii
index 005404975..abf329a99 100644
--- a/extensions/amp-yotpo/validator-amp-yotpo.protoascii
+++ b/extensions/amp-yotpo/validator-amp-yotpo.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-yotpo
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-yotpo"
@@ -28,7 +27,6 @@ tags: {  # amp-yotpo
 }
 tags: {  # <amp-yotpo>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-YOTPO"
   requires_extension: "amp-yotpo"
   attr_lists: "extended-amp-global"
diff --git a/extensions/amp-youtube/validator-amp-youtube.protoascii b/extensions/amp-youtube/validator-amp-youtube.protoascii
index 3923f0fd1..31ea7b469 100644
--- a/extensions/amp-youtube/validator-amp-youtube.protoascii
+++ b/extensions/amp-youtube/validator-amp-youtube.protoascii
@@ -16,7 +16,6 @@
 
 tags: {  # amp-youtube
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   extension_spec: {
     name: "amp-youtube"
@@ -29,7 +28,6 @@ tags: {  # amp-youtube
 }
 tags: {  # <amp-youtube>
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "AMP-YOUTUBE"
   requires_extension: "amp-youtube"
   attrs: { name: "autoplay" }
diff --git a/validator/validator-css.protoascii b/validator/validator-css.protoascii
index 169692072..f1af32060 100644
--- a/validator/validator-css.protoascii
+++ b/validator/validator-css.protoascii
@@ -250,7 +250,10 @@ declaration_list {
   declaration: { name: "word-spacing" }
   declaration: { name: "word-wrap" }
   declaration: { name: "writing-mode" }
-  declaration: { name: "z-index" }
+  declaration: {
+     name: "z-index"
+     value_regex_casei: "auto|initial|inherit|[-+]?[0-9]+"
+  }
 }
 
 declaration_list {
@@ -302,13 +305,260 @@ declaration_list {
 }
 
 declaration_list {
-  name: "EMAIL_SPECIFIC_VENDOR_PREFIXES"
-  # data-css-strict AMP Email does not enable automatic expansion of vendor
-  # prefixes on CSS properties. Instead, these are the only 3 vendor-prefixed
-  # CSS properties which data-css-strict email explicitly supports.
+  name: "EMAIL_SPECIFIC_DECLARATIONS"
+  # AMP4EMAIL supported properties:
+  # https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-css/#supported-css-properties
   declaration: { name: "-moz-appearance" }
   declaration: { name: "-webkit-appearance" }
   declaration: { name: "-webkit-tap-highlight-color" }
+  declaration: { name: "align-content" }
+  declaration: { name: "align-items" }
+  declaration: { name: "align-self" }
+  declaration: { name: "appearance" }
+  declaration: { name: "azimuth" }
+  declaration: { name: "background" }
+  declaration: { name: "background-attachment" }
+  declaration: { name: "background-blend-mode" }
+  declaration: { name: "background-clip" }
+  declaration: { name: "background-color" }
+  declaration: { name: "background-image" }
+  declaration: { name: "background-origin" }
+  declaration: { name: "background-position" }
+  declaration: { name: "background-repeat" }
+  declaration: { name: "background-size" }
+  declaration: { name: "border" }
+  declaration: { name: "border-bottom" }
+  declaration: { name: "border-bottom-color" }
+  declaration: { name: "border-bottom-left-radius" }
+  declaration: { name: "border-bottom-right-radius" }
+  declaration: { name: "border-bottom-style" }
+  declaration: { name: "border-bottom-width" }
+  declaration: { name: "border-collapse" }
+  declaration: { name: "border-color" }
+  declaration: { name: "border-left" }
+  declaration: { name: "border-left-color" }
+  declaration: { name: "border-left-style" }
+  declaration: { name: "border-left-width" }
+  declaration: { name: "border-radius" }
+  declaration: { name: "border-right" }
+  declaration: { name: "border-right-color" }
+  declaration: { name: "border-right-style" }
+  declaration: { name: "border-right-width" }
+  declaration: { name: "border-spacing" }
+  declaration: { name: "border-style" }
+  declaration: { name: "border-top" }
+  declaration: { name: "border-top-color" }
+  declaration: { name: "border-top-left-radius" }
+  declaration: { name: "border-top-right-radius" }
+  declaration: { name: "border-top-style" }
+  declaration: { name: "border-top-width" }
+  declaration: { name: "border-width" }
+  declaration: { name: "bottom" }
+  declaration: { name: "box-shadow" }
+  declaration: { name: "box-sizing" }
+  declaration: { name: "break-after" }
+  declaration: { name: "break-before" }
+  declaration: { name: "break-inside" }
+  declaration: { name: "caption-side" }
+  declaration: { name: "caret-color" }
+  declaration: { name: "clear" }
+  declaration: { name: "color" }
+  declaration: { name: "color-adjust" }
+  declaration: { name: "column-count" }
+  declaration: { name: "column-fill" }
+  declaration: { name: "column-gap" }
+  declaration: { name: "column-rule" }
+  declaration: { name: "column-rule-color" }
+  declaration: { name: "column-rule-style" }
+  declaration: { name: "column-rule-width" }
+  declaration: { name: "column-span" }
+  declaration: { name: "column-width" }
+  declaration: { name: "columns" }
+  declaration: { name: "counter-increment" }
+  declaration: { name: "counter-reset" }
+  declaration: {
+    name: "cursor"
+    value_casei: "initial"
+    value_casei: "pointer"
+  }
+  declaration: { name: "direction" }
+  declaration: { name: "display" }
+  declaration: { name: "elevation" }
+  declaration: { name: "empty-cells" }
+  declaration: {
+    name: "filter"
+    value_regex_casei: "^ *((blur|brightness|contrast|drop-shadow|grayscale|hue-rotate|invert|opacity|saturate|sepia)\\(([^() ]*|(rgb|rgba|hsl|hsla)\\([^()]*\\))( +([^() ]*|(rgb|rgba|hsl|hsla)\\([^()]*\\)))*\\) *)*$"
+  }
+  declaration: { name: "flex" }
+  declaration: { name: "flex-basis" }
+  declaration: { name: "flex-direction" }
+  declaration: { name: "flex-flow" }
+  declaration: { name: "flex-grow" }
+  declaration: { name: "flex-shrink" }
+  declaration: { name: "flex-wrap" }
+  declaration: { name: "float" }
+  declaration: { name: "font" }
+  declaration: { name: "font-family" }
+  declaration: { name: "font-feature-settings" }
+  declaration: { name: "font-kerning" }
+  declaration: { name: "font-size" }
+  declaration: { name: "font-size-adjust" }
+  declaration: { name: "font-stretch" }
+  declaration: { name: "font-style" }
+  declaration: { name: "font-synthesis" }
+  declaration: { name: "font-variant" }
+  declaration: { name: "font-variant-alternates" }
+  declaration: { name: "font-variant-caps" }
+  declaration: { name: "font-variant-east-asian" }
+  declaration: { name: "font-variant-ligatures" }
+  declaration: { name: "font-variant-numeric" }
+  declaration: { name: "font-variation-settings" }
+  declaration: { name: "font-weight" }
+  declaration: { name: "gap" }
+  declaration: { name: "grid" }
+  declaration: { name: "grid-area" }
+  declaration: { name: "grid-auto-columns" }
+  declaration: { name: "grid-auto-flow" }
+  declaration: { name: "grid-auto-rows" }
+  declaration: { name: "grid-column" }
+  declaration: { name: "grid-column-end" }
+  declaration: { name: "grid-column-start" }
+  declaration: { name: "grid-row" }
+  declaration: { name: "grid-row-end" }
+  declaration: { name: "grid-row-start" }
+  declaration: { name: "grid-template" }
+  declaration: { name: "grid-template-areas" }
+  declaration: { name: "grid-template-columns" }
+  declaration: { name: "grid-template-rows" }
+  declaration: { name: "height" }
+  declaration: { name: "hyphens" }
+  declaration: { name: "image-orientation" }
+  declaration: { name: "image-resolution" }
+  declaration: { name: "inline-size" }
+  declaration: { name: "isolation" }
+  declaration: { name: "justify-content" }
+  declaration: { name: "justify-items" }
+  declaration: { name: "justify-self" }
+  declaration: { name: "left" }
+  declaration: { name: "letter-spacing" }
+  declaration: { name: "line-break" }
+  declaration: { name: "line-height" }
+  declaration: { name: "list-style" }
+  declaration: { name: "list-style-position" }
+  declaration: { name: "list-style-type" }
+  declaration: { name: "margin" }
+  declaration: { name: "margin-bottom" }
+  declaration: { name: "margin-left" }
+  declaration: { name: "margin-right" }
+  declaration: { name: "margin-top" }
+  declaration: { name: "max-height" }
+  declaration: { name: "max-width" }
+  declaration: { name: "min-height" }
+  declaration: { name: "min-width" }
+  declaration: { name: "mix-blend-mode" }
+  declaration: { name: "object-fit" }
+  declaration: { name: "object-position" }
+  declaration: { name: "offset-distance" }
+  declaration: { name: "opacity" }
+  declaration: { name: "order" }
+  declaration: { name: "outline" }
+  declaration: { name: "outline-color" }
+  declaration: { name: "outline-offset" }
+  declaration: { name: "outline-style" }
+  declaration: { name: "outline-width" }
+  declaration: { name: "overflow" }
+  declaration: { name: "overflow-wrap" }
+  declaration: { name: "overflow-x" }
+  declaration: { name: "overflow-y" }
+  declaration: { name: "padding" }
+  declaration: { name: "padding-bottom" }
+  declaration: { name: "padding-left" }
+  declaration: { name: "padding-right" }
+  declaration: { name: "padding-top" }
+  declaration: { name: "pause" }
+  declaration: { name: "pause-after" }
+  declaration: { name: "pause-before" }
+  declaration: { name: "perspective" }
+  declaration: { name: "perspective-origin" }
+  declaration: { name: "pitch" }
+  declaration: { name: "pitch-range" }
+  declaration: { name: "place-items" }
+  # CSS property `position` with values `fixed` and `sticky` are not allowed.
+  # From https://www.w3schools.com/cssref/pr_class_position.asp
+  declaration: {
+    name: "position"
+    value_casei: "absolute"
+    value_casei: "inherit"
+    value_casei: "initial"
+    value_casei: "relative"
+    value_casei: "static"
+  }
+  declaration: { name: "quotes" }
+  declaration: { name: "resize" }
+  declaration: { name: "richness" }
+  declaration: { name: "right" }
+  declaration: { name: "row-gap" }
+  declaration: { name: "speak" }
+  declaration: { name: "speak-header" }
+  declaration: { name: "speak-numeral" }
+  declaration: { name: "speak-punctuation" }
+  declaration: { name: "speech-rate" }
+  declaration: { name: "stress" }
+  declaration: { name: "table-layout" }
+  declaration: { name: "text-align" }
+  declaration: { name: "text-align-last" }
+  declaration: { name: "text-combine-upright" }
+  declaration: { name: "text-decoration" }
+  declaration: { name: "text-decoration-color" }
+  declaration: { name: "text-decoration-line" }
+  declaration: { name: "text-decoration-skip" }
+  declaration: { name: "text-decoration-style" }
+  declaration: { name: "text-emphasis" }
+  declaration: { name: "text-emphasis-color" }
+  declaration: { name: "text-emphasis-position" }
+  declaration: { name: "text-emphasis-style" }
+  declaration: { name: "text-indent" }
+  declaration: { name: "text-justify" }
+  declaration: { name: "text-orientation" }
+  declaration: { name: "text-overflow" }
+  declaration: { name: "text-shadow" }
+  declaration: { name: "text-transform" }
+  declaration: { name: "text-underline-position" }
+  declaration: { name: "top" }
+  declaration: { name: "transform" }
+  declaration: { name: "transform-box" }
+  declaration: { name: "transform-origin" }
+  declaration: { name: "transform-style" }
+  declaration: {
+    name: "transition"
+    value_regex_casei: "^ *((initial|unset)|(((none|offset-distance|opacity|transform|visibility)( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(s|ms)( *(linear|(ease|ease-in|ease-out|ease-in-out|cubic-bezier\\( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(, *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?){3} *\\))|(step-start|step-end|steps\\( *(|-|\\+)[0-9]+(, *(jump-start|jump-end|jump-none|jump-both|start|end))? *\\)))( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(s|ms))?)?)?)(, *((none|offset-distance|opacity|transform|visibility)( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(s|ms)( *(linear|(ease|ease-in|ease-out|ease-in-out|cubic-bezier\\( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(, *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?){3} *\\))|(step-start|step-end|steps\\( *(|-|\\+)[0-9]+(, *(jump-start|jump-end|jump-none|jump-both|start|end))? *\\)))( *(|-|\\+)([0-9]+|[0-9]*\\.[0-9]+)(e(|-|\\+)?[0-9]+)?(s|ms))?)?)?))*)) *$"
+  }
+  declaration: { name: "transition-delay" }
+  declaration: { name: "transition-duration" }
+  declaration: {
+    name: "transition-property"
+    value_regex_casei: "^ *(initial|unset|(none|offset-distance|opacity|transform|visibility)(, *(none|offset-distance|opacity|transform|visibility))*) *$"
+  }
+  declaration: { name: "transition-timing-function" }
+  declaration: { name: "unicode-bidi" }
+  declaration: { name: "vertical-align" }
+  declaration: {
+    name: "visibility"
+    value_casei: "hidden"
+    value_casei: "initial"
+    value_casei: "visible"
+  }
+  declaration: { name: "voice-family" }
+  declaration: { name: "white-space" }
+  declaration: { name: "width" }
+  declaration: { name: "word-break" }
+  declaration: { name: "word-spacing" }
+  declaration: { name: "word-wrap" }
+  declaration: { name: "writing-mode" }
+  declaration: {
+    name: "z-index"
+    value_regex_casei: "([-+]?0)|([-+]?100)|([-+]?[1-9][0-9]?)"
+  }
 }
 
 # DocCSS rules for AMP for non-transformed documents.
@@ -382,40 +632,6 @@ css {
   declaration_list: "AMP_ONLY_DECLARATIONS"
 }
 
-# DocCss rules for ACTIONS
-css {
-  html_format: ACTIONS
-  spec_url:
-  "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets"
-
-  # Due to a bug, we allowed unlimited doc-level bytes for CSS in ACTIONS
-  # formats. To avoid breaking existing docs, this is temporarily allowed until
-  # we determine the next course of action.
-  # max_bytes: 75000
-  # max_bytes_per_inline_style: 1000
-  max_bytes_spec_url:
-  "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#maximum-size"
-  url_bytes_included: true
-
-  allow_all_declaration_in_style_tag: true
-  allow_important: false
-  image_url_spec: {
-    protocol: "https"
-    protocol: "http"
-    protocol: "data"
-    allow_empty: true
-  }
-  font_url_spec: {
-    protocol: "https"
-    protocol: "http"
-    protocol: "data"
-    allow_empty: true
-  }
-  expand_vendor_prefixes: true
-  declaration_list: "BASIC_DECLARATIONS"
-  declaration_list_svg: "SVG_BASIC_DECLARATIONS"
-}
-
 # DocCss rules for AMP4ADS.
 css {
   html_format: AMP4ADS
@@ -450,7 +666,7 @@ css {
 css {
   html_format: AMP4EMAIL
   disabled_by: "data-css-strict"
-  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets"
+  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-css"
 
   # Due to a bug, we allowed unlimited doc-level bytes for CSS in AMP4EMAIL
   # formats. To avoid breaking emails, this is temporarily set to a warning but
@@ -481,12 +697,13 @@ css {
 css {
   html_format: AMP4EMAIL
   enabled_by: "data-css-strict"
-  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets"
+  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-css"
 
   max_bytes_is_warning: false
   max_bytes: 75000
   max_bytes_per_inline_style: 1000
 
+  # TODO(b/162314127): add maximum size documentation to the email spec
   max_bytes_spec_url:
   "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#maximum-size"
   url_bytes_included: true
@@ -497,9 +714,7 @@ css {
     protocol: "https"
   }
   expand_vendor_prefixes: false
-  declaration_list: "BASIC_DECLARATIONS"
-  declaration_list: "EMAIL_SPECIFIC_VENDOR_PREFIXES"
-  declaration_list_svg: "SVG_BASIC_DECLARATIONS"
+  declaration_list: "EMAIL_SPECIFIC_DECLARATIONS"
 }
 
 # This variant of <style amp-custom> is designed to help developers see how
@@ -513,7 +728,6 @@ tags: {  # <style amp-custom-length-check>, ALL FORMATS
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "STYLE"
   spec_name: "style amp-custom-length-check"
   descriptive_name: "style amp-custom-length-check"
@@ -536,9 +750,8 @@ tags: {  # <style amp-custom-length-check>, ALL FORMATS
   }
 }
 
-tags: {  # <style amp-custom>, [AMP, ACTIONS]
+tags: {  # <style amp-custom>, [AMP]
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "STYLE"
   spec_name: "style amp-custom"
   descriptive_name: "style amp-custom"
@@ -671,7 +884,6 @@ tags: {  # <style amp-custom>, AMP4EMAIL, not data-css-strict
     name: "type"
     value_casei: "text/css"
   }
-  # TODO(b/68756045): Allowlist CSS properties allowed in Dynamic Mail.
   cdata: {
     doc_css_bytes: true
     max_bytes: 75000
@@ -686,6 +898,13 @@ tags: {  # <style amp-custom>, AMP4EMAIL, not data-css-strict
           type: 'all'
           type: 'screen'
           feature: 'device-width'
+          feature: 'hover'
+          feature: 'max-device-width'
+          feature: 'max-resolution'
+          feature: 'max-width'
+          feature: 'min-device-width'
+          feature: 'min-resolution'
+          feature: 'min-width'
           feature: 'orientation'
           feature: 'pointer'
           feature: 'resolution'
@@ -705,7 +924,7 @@ tags: {  # <style amp-custom>, AMP4EMAIL, not data-css-strict
       error_message: "CSS i-amphtml- name prefix"
     }
   }
-  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets"
+  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-css"
 }
 
 tags: {  # <style amp-custom>, AMP4EMAIL, data-css-strict
@@ -730,7 +949,6 @@ tags: {  # <style amp-custom>, AMP4EMAIL, data-css-strict
     name: "type"
     value_casei: "text/css"
   }
-  # TODO(b/68756045): Allowlist CSS properties allowed in Dynamic Mail.
   cdata: {
     doc_css_bytes: true
     max_bytes: 75000
@@ -745,15 +963,20 @@ tags: {  # <style amp-custom>, AMP4EMAIL, data-css-strict
           type: 'all'
           type: 'screen'
           feature: 'device-width'
+          feature: 'hover'
+          feature: 'max-device-width'
+          feature: 'max-resolution'
+          feature: 'max-width'
+          feature: 'min-device-width'
+          feature: 'min-resolution'
+          feature: 'min-width'
           feature: 'orientation'
           feature: 'pointer'
           feature: 'resolution'
           feature: 'width'
         }
       }
-      at_rule_spec: { name: 'page' }
       selector_spec: {
-        attribute_name: "foo"
         attribute_name: "active"
         attribute_name: "alt"
         attribute_name: "autocomplete"
@@ -792,6 +1015,35 @@ tags: {  # <style amp-custom>, AMP4EMAIL, data-css-strict
         attribute_name: "type"
         attribute_name: "value"
         attribute_name: "width"
+        pseudo_class: "active"
+        pseudo_class: "checked"
+        pseudo_class: "default"
+        pseudo_class: "disabled"
+        pseudo_class: "empty"
+        pseudo_class: "enabled"
+        pseudo_class: "first-child"
+        pseudo_class: "first-of-type"
+        pseudo_class: "focus"
+        pseudo_class: "focus-within"
+        pseudo_class: "hover"
+        pseudo_class: "in-range"
+        pseudo_class: "indeterminate"
+        pseudo_class: "invalid"
+        pseudo_class: "last-child"
+        pseudo_class: "last-of-type"
+        pseudo_class: "not"
+        pseudo_class: "nth-child"
+        pseudo_class: "nth-last-child"
+        pseudo_class: "nth-last-of-type"
+        pseudo_class: "nth-of-type"
+        pseudo_class: "only-child"
+        pseudo_class: "only-of-type"
+        pseudo_class: "optional"
+        pseudo_class: "out-of-range"
+        pseudo_class: "read-only"
+        pseudo_class: "read-write"
+        pseudo_class: "required"
+        pseudo_class: "valid"
       }
     }
     disallowed_cdata_regex: {
@@ -805,12 +1057,11 @@ tags: {  # <style amp-custom>, AMP4EMAIL, data-css-strict
       error_message: "CSS i-amphtml- name prefix"
     }
   }
-  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#stylesheets"
+  spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-css"
 }
 
-tags: {  # `<style amp-boilerplate>`, [AMP, ACTIONS]
+tags: {  # `<style amp-boilerplate>`, [AMP]
   html_format: AMP
-  html_format: ACTIONS
   disabled_by: "transformed"
   tag_name: "STYLE"
   spec_name: "head > style[amp-boilerplate]"
@@ -834,15 +1085,15 @@ tags: {  # `<style amp-boilerplate>`, [AMP, ACTIONS]
   spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amp-boilerplate/?format=websites"
 }
 
-tags: {  # `<style amp-boilerplate>`, transformed [AMP, ACTIONS]
+tags: {  # `<style amp-boilerplate>`, transformed [AMP]
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "STYLE"
   spec_name: "head > style[amp-boilerplate] (transformed)"
   descriptive_name: "head > style[amp-boilerplate]"
   unique: true
   mandatory_parent: "HEAD"
+  attr_lists: "nonce-attr"
   attrs: {
     name: "amp-boilerplate"
     mandatory: true
@@ -906,9 +1157,8 @@ tags: {  # `<style amp4email-boilerplate>`, AMP4EMAIL
   spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/?format=email#required-markup"
 }
 
-tags: {  # `<style amp-boilerplate>`, [AMP, ACTIONS]
+tags: {  # `<style amp-boilerplate>`, [AMP]
   html_format: AMP
-  html_format: ACTIONS
   disabled_by: "transformed"
   tag_name: "STYLE"
   spec_name: "noscript > style[amp-boilerplate]"
@@ -931,9 +1181,8 @@ tags: {  # `<style amp-boilerplate>`, [AMP, ACTIONS]
   spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amp-boilerplate/?format=websites"
 }
 
-tags: {  # `<style amp-boilerplate>`, transformed [AMP, ACTIONS]
+tags: {  # `<style amp-boilerplate>`, transformed [AMP]
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "STYLE"
   spec_name: "noscript > style[amp-boilerplate] (transformed)"
@@ -941,6 +1190,7 @@ tags: {  # `<style amp-boilerplate>`, transformed [AMP, ACTIONS]
   unique: true
   mandatory_parent: "NOSCRIPT"
   mandatory_ancestor: "HEAD"
+  attr_lists: "nonce-attr"
   attrs: {
     name: "amp-boilerplate"
     mandatory: true
@@ -954,10 +1204,9 @@ tags: {  # `<style amp-boilerplate>`, transformed [AMP, ACTIONS]
   spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amp-boilerplate/?format=websites"
 }
 
-tags: {  # `<style amp-keyframes>`, [AMP, AMP4ADS, ACTIONS]
+tags: {  # `<style amp-keyframes>`, [AMP, AMP4ADS]
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "STYLE"
   spec_name: "style[amp-keyframes]"
   descriptive_name: "style[amp-keyframes]"
@@ -1000,6 +1249,7 @@ tags: {  # '<style amp-runtime>`, transformed AMP
   mandatory: true
   unique: true
   mandatory_parent: "HEAD"
+  attr_lists: "nonce-attr"
   attrs: {
     name: "amp-runtime"
     mandatory: true
diff --git a/validator/validator-main.protoascii b/validator/validator-main.protoascii
index 7efdb8ba0..aa6d96612 100644
--- a/validator/validator-main.protoascii
+++ b/validator/validator-main.protoascii
@@ -20,13 +20,13 @@
 # in production from crashing. This id is not relevant to validator.js
 # because thus far, engine (validator.js) and spec file
 # (validator-main.protoascii, etc) are always released together.
-min_validator_revision_required: 474
+min_validator_revision_required: 475
 
 # The spec file revision allows the validator engine to distinguish
 # newer versions of the spec file. This is currently a Google internal
 # mechanism, validator.js does not use this facility. However, any
 # change to this file (validator-main.js) requires updating this revision id.
-spec_file_revision: 1060
+spec_file_revision: 1095
 
 styles_spec_url: "https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/style_pages/"
 script_spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/validation-workflow/validation_errors/#custom-javascript-is-not-allowed"
@@ -41,10 +41,15 @@ script_spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/valid
 # Rules for AMP HTML
 # https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml
 
+doc: {
+  html_format: AMP4EMAIL
+  max_bytes: 100000
+  max_bytes_spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/?format=email"
+}
+
 tags: {
   html_format: AMP
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "!DOCTYPE"
   spec_name: "html doctype"
   descriptive_name: "html !doctype"
@@ -92,7 +97,6 @@ tags: {  # HTML tag for non-transformed AMP.
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   disabled_by: "transformed"
   tag_name: "HTML"
   mandatory: true
@@ -110,7 +114,6 @@ tags: {  # HTML tag for non-transformed AMP.
 }
 tags: {  # HTML tag for transformed AMP.
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "HTML"
   spec_name: "html (transformed)"
@@ -134,7 +137,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "HEAD"
   mandatory: true
   mandatory_parent: "HTML"
@@ -145,7 +147,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TITLE"
   spec_name: "title"
   attrs: { name: "[text]" }
@@ -163,7 +164,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "BASE"
   unique: true
   mandatory_parent: "HEAD"
@@ -197,7 +197,6 @@ attr_lists: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link rel="
   disallowed_ancestor: "TEMPLATE"
@@ -237,7 +236,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link rel=canonical"
   descriptive_name: "link rel=canonical"
@@ -291,7 +289,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link rel=preload"
   descriptive_name: "link rel=preload"
@@ -304,6 +301,15 @@ tags: {
     value_casei: "preload"
     dispatch_key: NAME_VALUE_DISPATCH
   }
+  attrs: {
+    name: "imagesrcset"
+    value_url: {
+      protocol: "http"
+      protocol: "https"
+    }
+    disallowed_value_regex: "__amp_source_origin"
+  }
+  attrs: { name: "imagesizes" }
   attr_lists: "common-link-attrs"
   spec_url: "https://amp.dev/documentation/guides-and-tutorials/learn/spec/amphtml/#html-tags"
 }
@@ -311,7 +317,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link rel=stylesheet for fonts"
   descriptive_name: "link rel=stylesheet for fonts"
@@ -356,7 +361,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link itemprop=sameAs"
   descriptive_name: "link itemprop=sameAs"
@@ -377,7 +381,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link itemprop="
   descriptive_name: "link itemprop="
@@ -396,7 +399,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINK"
   spec_name: "link property="
   descriptive_name: "link property="
@@ -417,7 +419,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta charset=utf-8"
   descriptive_name: "meta charset=utf-8"
@@ -435,7 +436,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta name=viewport"
   descriptive_name: "meta name=viewport"
@@ -469,7 +469,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=X-UA-Compatible"
   descriptive_name: "meta http-equiv=X-UA-Compatible"
@@ -714,7 +713,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta name= and content="
   attrs: { name: "content" }
@@ -742,7 +740,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=Content-Type"
   mandatory_ancestor: "HEAD"
@@ -763,7 +760,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=content-language"
   mandatory_ancestor: "HEAD"
@@ -784,7 +780,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=pics-label"
   mandatory_ancestor: "HEAD"
@@ -805,7 +800,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=imagetoolbar"
   mandatory_ancestor: "HEAD"
@@ -826,7 +820,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=Content-Style-Type"
   mandatory_ancestor: "HEAD"
@@ -848,7 +841,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=Content-Script-Type"
   mandatory_ancestor: "HEAD"
@@ -869,7 +861,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=origin-trial"
   mandatory_ancestor: "HEAD"
@@ -890,7 +881,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta http-equiv=resource-type"
   mandatory_ancestor: "HEAD"
@@ -950,7 +940,6 @@ tags: {
 # Enables AMP-to-AMP navigation
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "META"
   spec_name: "meta name=amp-to-amp-navigation"
   mandatory_parent: "HEAD"
@@ -1053,7 +1042,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "BODY"
   mandatory: true
   unique: true
@@ -1065,7 +1053,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "ARTICLE"
 }
 # 4.3.3 The section element
@@ -1083,7 +1070,6 @@ attr_lists: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SECTION"
   disallowed_ancestor: "AMP-ACCORDION"
   attr_lists: "poool-access-attrs"
@@ -1099,7 +1085,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "NAV"
 }
 # 4.3.5 The aside element
@@ -1107,7 +1092,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "ASIDE"
 }
 # 4.3.6 The h1, h2, h3, h4, h5, and h6 elements
@@ -1115,7 +1099,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H1"
   attrs: { name: "align" }
 }
@@ -1123,7 +1106,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H2"
   attrs: { name: "align" }
 }
@@ -1131,7 +1113,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H3"
   attrs: { name: "align" }
 }
@@ -1139,7 +1120,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H4"
   attrs: { name: "align" }
 }
@@ -1147,7 +1127,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H5"
   attrs: { name: "align" }
 }
@@ -1155,7 +1134,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "H6"
   attrs: { name: "align" }
 }
@@ -1164,7 +1142,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "HEADER"
 }
 # 4.3 7 The footer element
@@ -1172,7 +1149,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "FOOTER"
 }
 # 4.3 7 The address element
@@ -1180,7 +1156,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "ADDRESS"
 }
 
@@ -1190,7 +1165,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "P"
   attrs: { name: "align" }
 }
@@ -1199,7 +1173,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "HR"
 }
 # 4.4.3 The pre element
@@ -1207,7 +1180,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "PRE"
 }
 # 4.4.4 The blockquote element
@@ -1227,7 +1199,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "BLOCKQUOTE"
   attrs: { name: "align" }
   attr_lists: "cite-attr"
@@ -1237,7 +1208,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "OL"
   attrs: {
     name: "reversed"
@@ -1257,7 +1227,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "UL"
 }
 # 4.4.7 The li element
@@ -1265,7 +1234,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "LI"
   attrs: {
     name: "value"
@@ -1277,7 +1245,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DL"
 }
 # 4.4.9 The dt element
@@ -1285,7 +1252,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DT"
 }
 # 4.4.10 The dd element
@@ -1293,7 +1259,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DD"
 }
 # 4.4.11 The figure element
@@ -1301,7 +1266,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "FIGURE"
 }
 # 4.4.12 The figcaption element
@@ -1309,7 +1273,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "FIGCAPTION"
 }
 # 4.4.13 The div element
@@ -1317,7 +1280,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   attrs: { name: "align" }
 }
@@ -1326,7 +1288,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "MAIN"
 }
 
@@ -1335,7 +1296,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "A"
   attrs: { name: "border" }  # Not valid html5 but commonly used and supported.
   attrs: { name: "download" }
@@ -1502,7 +1462,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "EM"
 }
 # 4.5.3 The strong element
@@ -1510,7 +1469,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "STRONG"
 }
 # 4.5.4 The small element
@@ -1518,7 +1476,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SMALL"
 }
 # 4.5.5 The s element
@@ -1526,7 +1483,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "S"
 }
 # 4.5.6 The cite element
@@ -1534,7 +1490,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "CITE"
 }
 # 4.5.7 The q element
@@ -1542,7 +1497,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "Q"
   attr_lists: "cite-attr"
 }
@@ -1551,7 +1505,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DFN"
 }
 # 4.5.9 The abbr element
@@ -1559,7 +1512,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "ABBR"
 }
 # 4.5.10 The data element
@@ -1567,7 +1519,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DATA"
 }
 # 4.5.11 The time element
@@ -1575,7 +1526,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TIME"
   attrs: {
     name: "datetime"
@@ -1590,7 +1540,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "CODE"
 }
 # 4.5.13 The var element
@@ -1598,7 +1547,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "VAR"
 }
 # 4.5.14 The samp element
@@ -1606,7 +1554,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SAMP"
 }
 # 4.5.15 The kbd element
@@ -1614,7 +1561,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "KBD"
 }
 # 4.5.16 The sub and sup elements
@@ -1622,14 +1568,12 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SUB"
 }
 tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SUP"
 }
 # 4.5.17 The i element
@@ -1637,7 +1581,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "I"
 }
 # 4.5.18 The b element
@@ -1645,7 +1588,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "B"
 }
 # 4.5.19 The u element
@@ -1653,7 +1595,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "U"
 }
 # 4.5.20 The mark element
@@ -1661,7 +1602,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "MARK"
 }
 # 4.5.21 The ruby element
@@ -1669,7 +1609,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "RUBY"
 }
 # 4.5.22 The rb element
@@ -1677,7 +1616,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "RB"
 }
 # 4.5.23 The rt element
@@ -1685,14 +1623,12 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "RT"
 }
 # 4.5.24 The rtc element
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "RTC"
 }
 # 4.5.25 The rp element
@@ -1700,14 +1636,12 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "RP"
 }
 # 4.5.26 The bdi element
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "BDI"
 }
 # 4.5.27 The bdo element
@@ -1715,7 +1649,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "BDO"
   attrs: { name: "dir" }
 }
@@ -1724,7 +1657,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SPAN"
 }
 # 4.5.29 The br element
@@ -1732,7 +1664,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "BR"
 }
 # 4.5.30 The wbr element
@@ -1740,7 +1671,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "WBR"
 }
 
@@ -1750,7 +1680,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "INS"
   # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins
   # These attributes have specific formatting, but as they are metadata
@@ -1764,7 +1693,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DEL"
   # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del
   # These attributes have specific formatting, but as they are metadata
@@ -1776,7 +1704,7 @@ tags: {
 
 # 4.7 Embedded Content
 # AMP HTML allows embedded content only via its own tags (e.g. amp-img), with
-# the exception of tags inside of a <noscript> ancestor.
+# the exception of tags inside of a <noscript> ancestor and transformed amp-img.
 # 4.7.1 The img element
 tags: {
   html_format: AMP  # Disallowed in AMP4ADS because <noscript> is disallowed.
@@ -1953,7 +1881,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOURCE"
   spec_name: "amp-video > source"
   mandatory_parent: "AMP-VIDEO"
@@ -1975,7 +1902,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOURCE"
   spec_name: "amp-audio > source"
   mandatory_parent: "AMP-AUDIO"
@@ -1997,7 +1923,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOURCE"
   spec_name: "audio > source"
   mandatory_parent: "AUDIO"
@@ -2020,7 +1945,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOURCE"
   spec_name: "video > source"
   mandatory_parent: "VIDEO"
@@ -2043,7 +1967,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOURCE"
   spec_name: "amp-ima-video > source"
   mandatory_parent: "AMP-IMA-VIDEO"
@@ -2122,7 +2045,6 @@ attr_lists: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "audio > track"
   mandatory_parent: "AUDIO"
@@ -2131,7 +2053,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "audio > track[kind=subtitles]"
   mandatory_parent: "AUDIO"
@@ -2140,7 +2061,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "video > track"
   mandatory_parent: "VIDEO"
@@ -2149,7 +2069,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "video > track[kind=subtitles]"
   mandatory_parent: "VIDEO"
@@ -2158,7 +2077,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "amp-audio > track"
   mandatory_parent: "AMP-AUDIO"
@@ -2171,7 +2089,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "amp-audio > track[kind=subtitles]"
   mandatory_parent: "AMP-AUDIO"
@@ -2184,7 +2101,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "amp-video > track"
   mandatory_parent: "AMP-VIDEO"
@@ -2197,7 +2113,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TRACK"
   spec_name: "amp-video > track[kind=subtitles]"
   mandatory_parent: "AMP-VIDEO"
@@ -2366,7 +2281,6 @@ attr_lists: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "G"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2380,7 +2294,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "GLYPH"
   mandatory_ancestor: "SVG"
   attrs: { name: "arabic-form" }
@@ -2400,7 +2313,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "GLYPHREF"
   mandatory_ancestor: "SVG"
   attrs: { name: "dx" }
@@ -2418,7 +2330,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "IMAGE"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2456,7 +2367,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "MARKER"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2477,7 +2387,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "METADATA"
   mandatory_ancestor: "SVG"
   attr_lists: "svg-core-attributes"
@@ -2487,7 +2396,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "PATH"
   mandatory_ancestor: "SVG"
   attrs: { name: "d" }
@@ -2504,7 +2412,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SOLIDCOLOR"
   mandatory_ancestor: "SVG"
   attrs: { name: "solid-color" }
@@ -2517,7 +2424,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SVG"
   attrs: { name: "contentscripttype" }
   attrs: { name: "contentstyletype" }
@@ -2543,7 +2449,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SWITCH"
   mandatory_ancestor: "SVG"
   attr_lists: "svg-conditional-processing-attributes"
@@ -2555,7 +2460,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "VIEW"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2571,7 +2475,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "CIRCLE"
   mandatory_ancestor: "SVG"
   attrs: { name: "cx" }
@@ -2589,7 +2492,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "ELLIPSE"
   mandatory_ancestor: "SVG"
   attrs: { name: "cx" }
@@ -2608,7 +2510,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINE"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2627,7 +2528,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "POLYGON"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2643,7 +2543,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "POLYLINE"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2659,7 +2558,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "RECT"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2681,7 +2579,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TEXT"
   mandatory_ancestor: "SVG"
   attrs: { name: "dx" }
@@ -2703,7 +2600,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TEXTPATH"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2720,7 +2616,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TREF"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2734,7 +2629,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TSPAN"
   mandatory_ancestor: "SVG"
   attrs: { name: "dx" }
@@ -2755,7 +2649,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "CLIPPATH"
   mandatory_ancestor: "SVG"
   attrs: { name: "clippathunits" }
@@ -2770,7 +2663,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FILTER"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2790,7 +2682,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "HKERN"
   mandatory_ancestor: "SVG"
   attrs: { name: "g1" }
@@ -2805,7 +2696,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "LINEARGRADIENT"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2825,7 +2715,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "MASK"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2844,7 +2733,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "PATTERN"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2867,7 +2755,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "RADIALGRADIENT"
   mandatory_ancestor: "SVG"
   attrs: { name: "cx" }
@@ -2889,7 +2776,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "STOP"
   spec_name: "lineargradient > stop"
   mandatory_ancestor: "LINEARGRADIENT"
@@ -2902,7 +2788,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "STOP"
   spec_name: "radialgradient > stop"
   mandatory_ancestor: "RADIALGRADIENT"
@@ -2915,7 +2800,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "VKERN"
   mandatory_ancestor: "SVG"
   attrs: { name: "g1" }
@@ -2931,7 +2815,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "DEFS"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2945,7 +2828,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "SYMBOL"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2961,7 +2843,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "USE"
   mandatory_ancestor: "SVG"
   attrs: { name: "externalresourcesrequired" }
@@ -2981,7 +2862,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FECOLORMATRIX"
   mandatory_ancestor: "SVG"
   attrs: { name: "in" }
@@ -2996,7 +2876,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FECOMPOSITE"
   mandatory_ancestor: "SVG"
   attrs: { name: "in" }
@@ -3015,7 +2894,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FEFLOOD"
   mandatory_ancestor: "SVG"
   attr_lists: "svg-core-attributes"
@@ -3027,7 +2905,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FEGAUSSIANBLUR"
   mandatory_ancestor: "SVG"
   attrs: { name: "edgemode" }
@@ -3042,7 +2919,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FEMERGE"
   mandatory_ancestor: "SVG"
   attr_lists: "svg-core-attributes"
@@ -3054,7 +2930,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FEMERGENODE"
   mandatory_ancestor: "SVG"
   attrs: { name: "in" }
@@ -3065,7 +2940,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FEOFFSET"
   mandatory_ancestor: "SVG"
   attrs: { name: "dx" }
@@ -3081,7 +2955,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "DESC"
   mandatory_ancestor: "SVG"
   attr_lists: "svg-core-attributes"
@@ -3091,7 +2964,6 @@ tags: {
 tags: {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "TITLE"
   spec_name: "svg title"
   mandatory_ancestor: "SVG"
@@ -3112,7 +2984,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TABLE"
   attrs: { name: "align" }  # Not valid html5 but commonly used and supported.
   attrs: { name: "bgcolor" }  # Not valid html5 but commonly used and supported.
@@ -3134,7 +3005,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "CAPTION"
 }
 # 4.9.3 The colgroup element
@@ -3142,7 +3012,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "COLGROUP"
   attrs: { name: "span" }
 }
@@ -3151,7 +3020,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "COL"
   attrs: { name: "span" }
 }
@@ -3160,7 +3028,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TBODY"
 }
 # 4.9.6 The thead element
@@ -3168,7 +3035,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "THEAD"
 }
 # 4.9.7 The tfoot element
@@ -3176,7 +3042,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TFOOT"
 }
 # 4.9.8 The tr element
@@ -3184,7 +3049,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TR"
   # These attributes are not supported in HTML5, but are widely supported and
   # commonly found.
@@ -3198,7 +3062,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TD"
   attrs: { name: "align" }  # Not valid html5 but commonly used and supported.
   attrs: { name: "bgcolor" }  # Not valid html5 but commonly used and supported.
@@ -3214,7 +3077,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TH"
   attrs: { name: "abbr" }
   attrs: { name: "align" }  # Not valid html5 but commonly used and supported.
@@ -3239,7 +3101,6 @@ tags: {
 tags {  # <form method=GET ...>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "FORM"
   spec_name: "FORM [method=GET]"
   requires_extension: "amp-form"
@@ -3344,66 +3205,6 @@ tags {  # <form method=POST ...>
   }
   attr_lists: "form-name-attr"
 }
-# ACTIONS <form method=POST ...> for POST identity token
-tags: {  # <form method=POST ...>
-  html_format: ACTIONS
-  tag_name: "FORM"
-  spec_name: "FORM [method=POST] (ACTIONS)"
-  requires_extension: "amp-form"
-  disallowed_ancestor: "AMP-APP-BANNER"
-  attrs: { name: "accept" }
-  attrs: { name: "accept-charset" }
-  # For method=POST forms, we require `action-xhr` and disallow `action`.
-  attrs: {
-    name: "action-xhr"
-    mandatory: true
-    value_url: {
-      protocol: "https"
-      allow_relative: false
-    }
-    disallowed_value_regex: "__amp_source_origin|"
-        "{{|}}"    # Mustache is disallowed in action-xhr.
-  }
-  attrs: { name: "autocomplete" }
-  attrs: {
-    name: "crossorigin"
-    value: "amp-viewer-auth-token-via-post"
-    trigger: {
-      also_requires_attr: "action-xhr"
-    }
-  }
-  attrs: {
-    name: "custom-validation-reporting"
-    value: "as-you-go"
-    value: "interact-and-submit"
-    value: "show-all-on-submit"
-    value: "show-first-on-submit"
-  }
-  attrs: { name: "enctype" }
-  attrs: {
-    name: "method"
-    mandatory: true
-    value_casei: "post"
-    dispatch_key: NAME_VALUE_DISPATCH
-  }
-  attrs: { name: "novalidate" }
-  # The target attribute has no effect, and should not be in POST forms.
-  # However, in the past it was required, so disallowing it would break many
-  # pages. See: https://github.com/ampproject/amphtml/issues/5607
-  attrs: {
-    name: "target"
-    value_casei: "_blank"
-    value_casei: "_top"
-  }
-  attrs: {
-    name: "verify-xhr"
-    value_url: {
-      protocol: "https"
-    }
-    disallowed_value_regex: "__amp_source_origin"
-  }
-  attr_lists: "form-name-attr"
-}
 # AMP4EMAIL allows action-xhr and disallows action attribute. It also disallows
 # the use of mustache templates in action-xhr. The only allowed
 # protocol for action-xhr is https. Relative urls are disallowed. It also
@@ -3441,6 +3242,7 @@ tags {  # <form method=GET ...>
     value_casei: "get"
   }
   attrs: { name: "novalidate" }
+  attrs: { name: "xssi-prefix" }
 }
 tags {  # <form method=POST ...>
   html_format: AMP4EMAIL
@@ -3476,12 +3278,12 @@ tags {  # <form method=POST ...>
     dispatch_key: NAME_VALUE_DISPATCH
   }
   attrs: { name: "novalidate" }
+  attrs: { name: "xssi-prefix" }
 }
 # Will add verify state template if requested by users
 tags {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [verify-error]"
   mandatory_ancestor: "FORM"
@@ -3494,7 +3296,6 @@ tags {
 tags {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [verify-error][template]"
   mandatory_ancestor: "FORM"
@@ -3512,7 +3313,6 @@ tags {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [submitting]"
   mandatory_ancestor: "FORM"
@@ -3525,7 +3325,6 @@ tags {
 tags {
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   # AMP4EMAIL is omitted. There is additional latency in rendering A4E
   # templates, which reduces the time available to render the template during
   # the submitting state.
@@ -3546,7 +3345,6 @@ tags {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [submit-success]"
   mandatory_ancestor: "FORM"
@@ -3560,7 +3358,6 @@ tags {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [submit-success][template]"
   mandatory_ancestor: "FORM"
@@ -3578,7 +3375,6 @@ tags {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [submit-error]"
   mandatory_ancestor: "FORM"
@@ -3592,7 +3388,6 @@ tags {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DIV"
   spec_name: "FORM DIV [submit-error][template]"
   mandatory_ancestor: "FORM"
@@ -3694,7 +3489,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "LABEL"
   attrs: { name: "for" }
   spec_url: "https://amp.dev/documentation/components/amp-form/"
@@ -3705,7 +3499,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "INPUT"
   attrs: {
     disabled_by: "amp4email"
@@ -3776,7 +3569,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "BUTTON"
   attrs: {
     name: "disabled"
@@ -3831,7 +3623,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SELECT"
   attrs: {
     disabled_by: "amp4email"
@@ -3863,7 +3654,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DATALIST"
   spec_url: "https://amp.dev/documentation/components/amp-form/"
 }
@@ -3872,7 +3662,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "OPTGROUP"
   mandatory_parent: "SELECT"
   attrs: { name: "disabled" }
@@ -3887,7 +3676,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "OPTION"
   attrs: { name: "disabled" }
   attrs: { name: "label" }
@@ -3905,7 +3693,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "TEXTAREA"
   attrs: { name: "autocomplete" }
   attrs: {
@@ -3982,7 +3769,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "OUTPUT"
   attrs: { name: "for" }
   attrs: { name: "form" }
@@ -3993,7 +3779,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "PROGRESS"
   attrs: { name: "max" }
   attrs: { name: "value" }
@@ -4003,7 +3788,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "METER"
   attrs: { name: "high" }
   attrs: { name: "low" }
@@ -4017,7 +3801,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "FIELDSET"
   attrs: { name: "disabled" }
   # <amp-bind>
@@ -4029,7 +3812,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "LEGEND"
 }
 
@@ -4039,7 +3821,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "DETAILS"
   attrs: {
     name: "open"
@@ -4052,7 +3833,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SUMMARY"
   mandatory_parent: "DETAILS"
 }
@@ -4068,7 +3848,7 @@ tags: {
 # enforce that exactly one runtime script must be included. This tagspec is
 # for the standard runtime, while the one below it is an identical spec but for
 # the LTS runtime, with the only difference being the src attribute. The third
-# is the corresponding spec for AMP4EMAIL and ACTIONS.
+# is the corresponding spec for AMP4EMAIL.
 attr_lists: {
   name: "amphtml-engine-attrs"
   attrs: {
@@ -4135,9 +3915,8 @@ tags: {
 }
 tags: {
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SCRIPT"
-  spec_name: "amphtml engine v0.js script [AMP4EMAIL,ACTIONS]"
+  spec_name: "amphtml engine v0.js script [AMP4EMAIL]"
   descriptive_name: "amphtml engine v0.js script"
   mandatory: true
   unique: true
@@ -4187,7 +3966,6 @@ tags: {
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "script type=application/ld+json"
   descriptive_name: "script type=application/ld+json"
@@ -4208,7 +3986,6 @@ tags: {
 # AMP RTC (Real Time Config)
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "script id=amp-rtc"
   unique: true
@@ -4235,7 +4012,6 @@ tags: {
 # AMP IMA VIDEO
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SCRIPT"
   spec_name: "amp-ima-video > script[type=application/json]"
   descriptive_name: "script type=application/ld+json"
@@ -4257,7 +4033,6 @@ tags: {
 # 4.11.2 The noscript element
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   disabled_by: "transformed"
   tag_name: "NOSCRIPT"
   spec_name: "noscript enclosure for boilerplate"
@@ -4269,7 +4044,6 @@ tags: {
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "NOSCRIPT"
   spec_name: "noscript enclosure for boilerplate (transformed)"
@@ -4294,62 +4068,50 @@ tags: {
 # 11.2 Non-conforming features
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "ACRONYM"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "BIG"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "CENTER"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "DIR"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "HGROUP"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "LISTING"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "MULTICOL"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "NEXTID"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "NOBR"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SPACER"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "STRIKE"
 }
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "TT"
 }
 
@@ -4359,7 +4121,6 @@ tags: {
 # https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   tag_name: "SLOT"
   attr_lists: "name-attr"
 }
@@ -4472,7 +4233,6 @@ attr_lists: {
 tags: {  # <amp-img>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-IMG"
   attrs: { name: "alt" }
   attrs: { name: "attribution" }
@@ -4500,6 +4260,42 @@ tags: {  # <amp-img>
     supported_layouts: RESPONSIVE
   }
 }
+# A duplicate of amp-img, but requires i-amphtml-ssr flag.
+tags: {  # <amp-img i-amphtml-ssr>
+  html_format: AMP
+  enabled_by: "transformed"
+  tag_name: "AMP-IMG"
+  spec_name: "amp-img (transformed)"
+  attrs: {
+    dispatch_key: NAME_DISPATCH
+    name: "i-amphtml-ssr"
+    mandatory: true
+  }
+  attrs: { name: "alt" }
+  attrs: { name: "attribution" }
+  attrs: { name: "object-fit" }
+  attrs: { name: "object-position" }
+  attrs: { name: "placeholder" }
+  attrs: { name: "referrerpolicy" }
+  # <amp-bind>
+  attrs: { name: "[alt]" }
+  attrs: { name: "[attribution]" }
+  attrs: { name: "[src]" }
+  attrs: { name: "[srcset]" }
+  attr_lists: "extended-amp-global"
+  attr_lists: "lightboxable-elements"
+  attr_lists: "mandatory-src-or-srcset"
+  spec_url: "https://amp.dev/documentation/components/amp-img/"
+  amp_layout: {
+    supported_layouts: FILL
+    supported_layouts: FIXED
+    supported_layouts: FIXED_HEIGHT
+    supported_layouts: FLEX_ITEM
+    supported_layouts: INTRINSIC
+    supported_layouts: NODISPLAY
+    supported_layouts: RESPONSIVE
+  }
+}
 # See the restrictions on mandatory-src-amp4email, as well as the removal of
 # `object-fit` and `object-position`.
 tags: {  # <amp-img>
@@ -4509,7 +4305,6 @@ tags: {  # <amp-img>
   attrs: { name: "alt" }
   attrs: { name: "attribution" }
   attrs: { name: "placeholder" }
-  attrs: { name: "referrerpolicy" }
   attr_lists: "extended-amp-global"
   attr_lists: "mandatory-src-amp4email"
   # <amp-bind>
@@ -4529,7 +4324,6 @@ tags: {  # <amp-layout>
   html_format: AMP
   html_format: AMP4ADS
   html_format: AMP4EMAIL
-  html_format: ACTIONS
   tag_name: "AMP-LAYOUT"
   attr_lists: "extended-amp-global"
   spec_url: "https://amp.dev/documentation/components/amp-layout/"
@@ -4547,7 +4341,6 @@ tags: {  # <amp-layout>
 tags: {  # <amp-pixel>
   html_format: AMP
   html_format: AMP4ADS
-  html_format: ACTIONS
   tag_name: "AMP-PIXEL"
   attrs: { name: "allow-ssr-img" }
   attrs: {
@@ -4577,7 +4370,6 @@ tags: {  # <amp-pixel>
 # Transformed AMP specific tags.
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "I-AMPHTML-SIZER"
   spec_name: "I-AMPHTML-SIZER-RESPONSIVE"
@@ -4597,7 +4389,6 @@ tags: {
 
 tags: {
   html_format: AMP
-  html_format: ACTIONS
   enabled_by: "transformed"
   tag_name: "I-AMPHTML-SIZER"
   spec_name: "I-AMPHTML-SIZER-INTRINSIC"
@@ -4626,6 +4417,11 @@ tags: {
     value: "true"
     mandatory: true
   }
+  attrs: {
+    name: "class"
+    value: "i-amphtml-intrinsic-sizer"
+    mandatory: true
+  }
   attrs: {
     name: "role"
     value: "presentation"
@@ -4638,6 +4434,37 @@ tags: {
   }
 }
 
+tags: {
+  html_format: AMP
+  enabled_by: "transformed"
+  tag_name: "IMG"
+  spec_name: "amp-img > img (transformed)"
+  # Ideally we'd be able to use regular amp-img parent, but runtime currently
+  # requires an i-amphtml-ssr attribute on the amp-img. We could do away with
+  # that, though.
+  mandatory_parent: "amp-img (transformed)"
+  attrs: { name: "alt" }
+  attrs: { name: "attribution" }
+  attrs: { name: "object-fit" }
+  attrs: { name: "object-position" }
+  attrs: { name: "referrerpolicy" }
+  attrs: { name: "sizes" }
+  attrs: { name: "title" }
+  attr_lists: "mandatory-src-or-srcset"
+  # SSR requires these explicit attributes
+  attrs: {
+    name: "class"
+    value_regex: "i-amphtml-fill-content\\s+i-amphtml-replaced-content|"
+        "i-amphtml-replaced-content\\s+i-amphtml-fill-content"
+    mandatory: true
+  }
+  attrs: {
+    name: "decoding"
+    value: "async"
+    mandatory: true
+  }
+}
+
 # AMP Layout attributes: implied for TagSpecs with amp_layout field
 # set. Note that while these attributes are defined as optional here,
 # depending on amp layout the validator will examine these fields and
@@ -4666,7 +4493,6 @@ attr_lists: {
   name: "nonce-attr"
   attrs: {
     disabled_by: "amp4email"
-    disabled_by: "transformed"
     name: "nonce"
   }
 }
@@ -4685,7 +4511,6 @@ attr_lists: {
     value: "anonymous"
   }
   attrs: {
-    disabled_by: "transformed"
     disabled_by: "amp4email"
     name: "nonce"
   }
@@ -5478,12 +5303,11 @@ attr_lists: {
   # 3.2.5 HTML5 Global attributes.
   attrs: { name: "accesskey" }
   attrs: {
-    # attribute "class" for transformed is handled within the Validator engine.
-    # If this changes, please be sure to also update:
-    # amp-experiment 1.0 implementation.
-    disabled_by: "transformed"
     name: "class"
-    disallowed_value_regex: "(^|\\W)i-amphtml-"
+    # attribute "class" is handled within the Validator engine, since we need to
+    # handle transformed and non-transformed cases while still allowing "class"
+    # attribute generically.
+    # disallowed_value_regex: "(^|[\t\n\f\r ])i-amphtml-"
   }
   attrs: { name: "dir" }
   attrs: { name: "draggable" }
@@ -5879,85 +5703,86 @@ error_specificity { code: DUPLICATE_UNIQUE_TAG_WARNING specificity: 30 }
 error_specificity { code: STYLESHEET_TOO_LONG specificity: 31 }
 error_specificity { code: STYLESHEET_AND_INLINE_STYLE_TOO_LONG specificity: 32 }
 error_specificity { code: INLINE_STYLE_TOO_LONG specificity: 33 }
-error_specificity { code: CSS_SYNTAX_INVALID_AT_RULE specificity: 34 }
+error_specificity { code: INLINE_SCRIPT_TOO_LONG specificity: 34 }
+error_specificity { code: CSS_SYNTAX_INVALID_AT_RULE specificity: 35 }
 error_specificity {
-  code: MANDATORY_PROPERTY_MISSING_FROM_ATTR_VALUE specificity: 35
-}
-error_specificity { code: INVALID_PROPERTY_VALUE_IN_ATTR_VALUE specificity: 36 }
-error_specificity { code: DISALLOWED_PROPERTY_IN_ATTR_VALUE specificity: 37 }
-error_specificity { code: MUTUALLY_EXCLUSIVE_ATTRS specificity: 38 }
-error_specificity { code: UNESCAPED_TEMPLATE_IN_ATTR_VALUE specificity: 39 }
-error_specificity { code: TEMPLATE_PARTIAL_IN_ATTR_VALUE specificity: 40 }
-error_specificity { code: TEMPLATE_IN_ATTR_NAME specificity: 41 }
+  code: MANDATORY_PROPERTY_MISSING_FROM_ATTR_VALUE specificity: 36
+}
+error_specificity { code: INVALID_PROPERTY_VALUE_IN_ATTR_VALUE specificity: 37 }
+error_specificity { code: DISALLOWED_PROPERTY_IN_ATTR_VALUE specificity: 38 }
+error_specificity { code: MUTUALLY_EXCLUSIVE_ATTRS specificity: 39 }
+error_specificity { code: UNESCAPED_TEMPLATE_IN_ATTR_VALUE specificity: 40 }
+error_specificity { code: TEMPLATE_PARTIAL_IN_ATTR_VALUE specificity: 41 }
+error_specificity { code: TEMPLATE_IN_ATTR_NAME specificity: 42 }
 error_specificity {
-  code: INCONSISTENT_UNITS_FOR_WIDTH_AND_HEIGHT specificity: 42
-}
-error_specificity { code: MISSING_LAYOUT_ATTRIBUTES specificity: 43 }
-error_specificity { code: IMPLIED_LAYOUT_INVALID specificity: 44 }
-error_specificity { code: SPECIFIED_LAYOUT_INVALID specificity: 45 }
-error_specificity { code: ATTR_DISALLOWED_BY_IMPLIED_LAYOUT specificity: 46 }
-error_specificity { code: ATTR_DISALLOWED_BY_SPECIFIED_LAYOUT specificity: 47 }
-error_specificity { code: DUPLICATE_DIMENSION specificity: 48 }
-error_specificity { code: DISALLOWED_RELATIVE_URL specificity: 49 }
-error_specificity { code: MISSING_URL specificity: 50 }
-error_specificity { code: DISALLOWED_DOMAIN specificity: 51 }
-error_specificity { code: INVALID_URL_PROTOCOL specificity: 52 }
-error_specificity { code: INVALID_URL specificity: 53 }
-error_specificity { code: DISALLOWED_STYLE_ATTR specificity: 54 }
-error_specificity { code: CSS_SYNTAX_STRAY_TRAILING_BACKSLASH specificity: 55 }
-error_specificity { code: CSS_SYNTAX_UNTERMINATED_COMMENT specificity: 56 }
-error_specificity { code: CSS_SYNTAX_UNTERMINATED_STRING specificity: 57 }
-error_specificity { code: CSS_SYNTAX_BAD_URL specificity: 58 }
+  code: INCONSISTENT_UNITS_FOR_WIDTH_AND_HEIGHT specificity: 43
+}
+error_specificity { code: MISSING_LAYOUT_ATTRIBUTES specificity: 44 }
+error_specificity { code: IMPLIED_LAYOUT_INVALID specificity: 45 }
+error_specificity { code: SPECIFIED_LAYOUT_INVALID specificity: 46 }
+error_specificity { code: ATTR_DISALLOWED_BY_IMPLIED_LAYOUT specificity: 47 }
+error_specificity { code: ATTR_DISALLOWED_BY_SPECIFIED_LAYOUT specificity: 48 }
+error_specificity { code: DUPLICATE_DIMENSION specificity: 49 }
+error_specificity { code: DISALLOWED_RELATIVE_URL specificity: 50 }
+error_specificity { code: MISSING_URL specificity: 51 }
+error_specificity { code: DISALLOWED_DOMAIN specificity: 52 }
+error_specificity { code: INVALID_URL_PROTOCOL specificity: 53 }
+error_specificity { code: INVALID_URL specificity: 54 }
+error_specificity { code: DISALLOWED_STYLE_ATTR specificity: 55 }
+error_specificity { code: CSS_SYNTAX_STRAY_TRAILING_BACKSLASH specificity: 56 }
+error_specificity { code: CSS_SYNTAX_UNTERMINATED_COMMENT specificity: 57 }
+error_specificity { code: CSS_SYNTAX_UNTERMINATED_STRING specificity: 58 }
+error_specificity { code: CSS_SYNTAX_BAD_URL specificity: 59 }
 error_specificity {
-  code: CSS_SYNTAX_EOF_IN_PRELUDE_OF_QUALIFIED_RULE specificity: 59
+  code: CSS_SYNTAX_EOF_IN_PRELUDE_OF_QUALIFIED_RULE specificity: 60
 }
-error_specificity { code: CSS_SYNTAX_INVALID_DECLARATION specificity: 60 }
-error_specificity { code: CSS_SYNTAX_INCOMPLETE_DECLARATION specificity: 61 }
-error_specificity { code: CSS_SYNTAX_ERROR_IN_PSEUDO_SELECTOR specificity: 62 }
-error_specificity { code: CSS_SYNTAX_MISSING_SELECTOR specificity: 63 }
-error_specificity { code: CSS_SYNTAX_NOT_A_SELECTOR_START specificity: 64 }
+error_specificity { code: CSS_SYNTAX_INVALID_DECLARATION specificity: 61 }
+error_specificity { code: CSS_SYNTAX_INCOMPLETE_DECLARATION specificity: 62 }
+error_specificity { code: CSS_SYNTAX_ERROR_IN_PSEUDO_SELECTOR specificity: 63 }
+error_specificity { code: CSS_SYNTAX_MISSING_SELECTOR specificity: 64 }
+error_specificity { code: CSS_SYNTAX_NOT_A_SELECTOR_START specificity: 65 }
 error_specificity {
-  code: CSS_SYNTAX_UNPARSED_INPUT_REMAINS_IN_SELECTOR specificity: 65
-}
-error_specificity { code: CSS_SYNTAX_MISSING_URL specificity: 66 }
-error_specificity { code: CSS_SYNTAX_DISALLOWED_DOMAIN specificity: 67 }
-error_specificity { code: CSS_SYNTAX_INVALID_URL specificity: 68 }
-error_specificity { code: CSS_SYNTAX_INVALID_URL_PROTOCOL specificity: 69 }
-error_specificity { code: CSS_SYNTAX_DISALLOWED_RELATIVE_URL specificity: 70 }
-error_specificity { code: INCORRECT_NUM_CHILD_TAGS specificity: 71 }
-error_specificity { code: DISALLOWED_CHILD_TAG_NAME specificity: 72 }
-error_specificity { code: DISALLOWED_FIRST_CHILD_TAG_NAME specificity: 73 }
-error_specificity { code: CSS_SYNTAX_INVALID_ATTR_SELECTOR specificity: 74 }
+  code: CSS_SYNTAX_UNPARSED_INPUT_REMAINS_IN_SELECTOR specificity: 66
+}
+error_specificity { code: CSS_SYNTAX_MISSING_URL specificity: 67 }
+error_specificity { code: CSS_SYNTAX_DISALLOWED_DOMAIN specificity: 68 }
+error_specificity { code: CSS_SYNTAX_INVALID_URL specificity: 69 }
+error_specificity { code: CSS_SYNTAX_INVALID_URL_PROTOCOL specificity: 70 }
+error_specificity { code: CSS_SYNTAX_DISALLOWED_RELATIVE_URL specificity: 71 }
+error_specificity { code: INCORRECT_NUM_CHILD_TAGS specificity: 72 }
+error_specificity { code: DISALLOWED_CHILD_TAG_NAME specificity: 73 }
+error_specificity { code: DISALLOWED_FIRST_CHILD_TAG_NAME specificity: 74 }
+error_specificity { code: CSS_SYNTAX_INVALID_ATTR_SELECTOR specificity: 75 }
 error_specificity {
-  code: CHILD_TAG_DOES_NOT_SATISFY_REFERENCE_POINT specificity: 75
+  code: CHILD_TAG_DOES_NOT_SATISFY_REFERENCE_POINT specificity: 76
 }
-error_specificity { code: MANDATORY_REFERENCE_POINT_MISSING specificity: 76 }
-error_specificity { code: DUPLICATE_REFERENCE_POINT specificity: 77 }
-error_specificity { code: TAG_REFERENCE_POINT_CONFLICT specificity: 78 }
+error_specificity { code: MANDATORY_REFERENCE_POINT_MISSING specificity: 77 }
+error_specificity { code: DUPLICATE_REFERENCE_POINT specificity: 78 }
+error_specificity { code: TAG_REFERENCE_POINT_CONFLICT specificity: 79 }
 error_specificity {
   code: CHILD_TAG_DOES_NOT_SATISFY_REFERENCE_POINT_SINGULAR
-  specificity: 79
+  specificity: 80
 }
-error_specificity { code: CSS_SYNTAX_DISALLOWED_PROPERTY_VALUE specificity: 80 }
+error_specificity { code: CSS_SYNTAX_DISALLOWED_PROPERTY_VALUE specificity: 81 }
 error_specificity {
   code: CSS_SYNTAX_DISALLOWED_PROPERTY_VALUE_WITH_HINT
-  specificity: 81
+  specificity: 82
 }
 error_specificity {
   code: CSS_SYNTAX_PROPERTY_DISALLOWED_WITHIN_AT_RULE
-  specificity: 82
+  specificity: 83
 }
 error_specificity {
   code: CSS_SYNTAX_PROPERTY_DISALLOWED_TOGETHER_WITH
-  specificity: 83
+  specificity: 84
 }
 error_specificity {
   code: CSS_SYNTAX_PROPERTY_REQUIRES_QUALIFICATION
-  specificity: 84
+  specificity: 85
 }
 error_specificity {
   code: BASE_TAG_MUST_PRECEED_ALL_URLS
-  specificity: 85
+  specificity: 86
 }
 error_specificity { code: DISALLOWED_SCRIPT_TAG specificity: 102 }
 error_specificity { code: GENERAL_DISALLOWED_TAG specificity: 103 }
@@ -6012,27 +5837,30 @@ error_specificity {
   code: CSS_SYNTAX_DISALLOWED_PSEUDO_ELEMENT
   specificity: 122
 }
-
 error_specificity {
-  code: INVALID_UTF8
+  code: CSS_SYNTAX_DISALLOWED_IMPORTANT
   specificity: 123
 }
 error_specificity {
-  code: CSS_EXCESSIVELY_NESTED
+  code: INVALID_UTF8
   specificity: 124
 }
 error_specificity {
-  code: DOCUMENT_SIZE_LIMIT_EXCEEDED
+  code: CSS_EXCESSIVELY_NESTED
   specificity: 125
 }
 error_specificity {
-  code: VALUE_SET_MISMATCH
+  code: DOCUMENT_SIZE_LIMIT_EXCEEDED
   specificity: 126
 }
 error_specificity {
-  code: INVALID_DOCTYPE_HTML
+  code: VALUE_SET_MISMATCH
   specificity: 127
 }
+error_specificity {
+  code: INVALID_DOCTYPE_HTML
+  specificity: 128
+}
 error_specificity {
   code: DEV_MODE_ONLY
   # This should always trump any other error. It is asserting
@@ -6048,8 +5876,7 @@ error_formats {
 }
 error_formats {
   code: INVALID_DOCTYPE_HTML
-  format: "Invalid or missing doctype declaration. Should be <!doctype html>. "
-          "See https://amp.dev/documentation/guides-and-tutorials/start/create/basic_markup/"
+  format: "Invalid or missing doctype declaration. Should be '!doctype html'."
 }
 error_formats {
   code: MANDATORY_TAG_MISSING
@@ -6174,6 +6001,10 @@ error_formats {
   format: "The inline style specified in tag '%1' is too long - it "
           "contains %2 bytes whereas the limit is %3 bytes."
 }
+error_formats {
+  code: INLINE_SCRIPT_TOO_LONG
+  format: "The inline script is %1 bytes, which exceeds the limit of %2 bytes."
+}
 error_formats {
   code: MANDATORY_CDATA_MISSING_OR_INCORRECT
   format: "The mandatory text inside tag '%1' is missing or incorrect."
@@ -6486,6 +6317,10 @@ error_formats {
   format: "CSS syntax error in tag '%1' - the property '%2' is set "
           "to the disallowed value '%3'. Allowed values: %4."
 }
+error_formats {
+  code: CSS_SYNTAX_DISALLOWED_IMPORTANT
+  format: "Usage of the !important CSS qualifier is not allowed."
+}
 error_formats {
   code: CSS_SYNTAX_PROPERTY_DISALLOWED_WITHIN_AT_RULE
   format: "CSS syntax error in tag '%1' - the property '%2' is disallowed "

@westonruter westonruter added this to the v2.0.2 milestone Sep 9, 2020
@westonruter westonruter self-assigned this Sep 9, 2020
@google-cla google-cla bot added the cla: yes Signed the Google CLA label Sep 9, 2020
@westonruter westonruter force-pushed the update/amphtml-2008290323001 branch from be07024 to 4871fc6 Compare September 10, 2020 00:38
@westonruter westonruter added the WS:Core Work stream for Plugin core label Sep 10, 2020
Comment on lines -18527 to -18529
'class' => array(
'disallowed_value_regex' => '(^|\\W)i-amphtml-',
),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now sanitized via AMP_Style_Sanitizer.

@westonruter westonruter marked this pull request as ready for review September 12, 2020 00:23
@westonruter westonruter requested a review from pierlon September 12, 2020 00:23
@github-actions
Copy link
Contributor

Plugin builds for 3d0d68a are ready 🛎️!

Comment on lines +2299 to +2302
$results = array_merge(
$results,
$this->ampify_ruleset_selectors( $ruleset )
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$results would always be an empty array. no?

Suggested change
$results = array_merge(
$results,
$this->ampify_ruleset_selectors( $ruleset )
);
$results = $this->ampify_ruleset_selectors( $ruleset );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, if this if condition remains the first one to mutate $results. The idea behind merging is that it's how the logic below amends $results.

@westonruter westonruter changed the title Update AMP validator spec to 2008290323001 Update AMP validator spec to 2008290323001 and improve i-amphtml-* sanitization Sep 12, 2020
@westonruter westonruter merged commit 244a1a4 into develop Sep 12, 2020
@westonruter westonruter deleted the update/amphtml-2008290323001 branch September 12, 2020 04:39
@westonruter
Copy link
Member Author

westonruter commented Sep 17, 2020

QA Passed ✅

When the AMP plugin is active and I create a Web Story, the expected meta generator tags are present:

image

Previously these would be stripped out.

Also I created the Custom HTML block as shown before and I got the expected validation errors:

image

image

And the expected output is correct:

image

The class attribute is not removed:

<div title="What will come after?" data-hint="Look at the CSS!" class="testing">Test results: </div>

Previously it would have been removed along with the i-amphtml-test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelogged Whether the issue/PR has been added to release notes. cla: yes Signed the Google CLA WS:Core Work stream for Plugin core
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Validation errors are not reported for “i-amphtml” appearing in CSS
3 participants