Skip to content

Validate the handoff manifest against a JSON Schema and scaffold it on init - #2

Open
aswasif007 wants to merge 4 commits into
trunkfrom
improve/manifest-schema-validation
Open

Validate the handoff manifest against a JSON Schema and scaffold it on init#2
aswasif007 wants to merge 4 commits into
trunkfrom
improve/manifest-schema-validation

Conversation

@aswasif007

@aswasif007 aswasif007 commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds schema-driven validation of the handoff manifest to the a8c-integration CLI, and makes init produce a ready-to-fill manifest. The manifest (a8c-manifest.yaml) now has a formal JSON Schema as its single source of truth; validate checks against it, and additionally rejects unfilled placeholders.

Testing steps

  1. Pull the PR, and run pnpm install && pnpm build && pnpm link
  2. Run cd .. && a8c-integration init
  3. Fill up the inputs
  4. Go to the created directory
  5. Run a8c-integration validate. You should see some errors.
  6. Address the errors and run the validate command again. Now you should see green.
  7. Add an additional field to the manifest: foo: bar. Run the validate command again. You should see error again.

@aswasif007 aswasif007 changed the title Improve/manifest schema validation Validate the handoff manifest against a JSON Schema Jul 28, 2026
Add manifest.schema.ts — a JSON Schema covering integration identity,
documentation, plugin runtime, the runtime-config fields (types, patterns,
enums, autogen/note), telemetry, and release — and validate the manifest
against it with Ajv, replacing the hand-rolled presence checks. Rule 3 also
rejects unfilled init placeholders and cross-checks the config keys the plugin
declares (Config::REQUIRED_FIELDS / SENSITIVE_FIELDS) against
runtime_config.fields. Renames the manifest convention to a8c-manifest.yaml.
init fills the manifest fields it can derive from the integration name
(summary, release.changelog), seeds the partner-only fields it cannot
(support contact, documentation URLs) with a REPLACE_ME placeholder so
validate fails until they are filled, and leaves the scaffold as a plain
directory rather than initializing a git repo.
@aswasif007 aswasif007 changed the title Validate the handoff manifest against a JSON Schema Validate the handoff manifest against a JSON Schema and scaffold it on init Jul 28, 2026
@aswasif007
aswasif007 force-pushed the improve/manifest-schema-validation branch from 74a0e24 to 1a2267d Compare July 28, 2026 13:58
@aswasif007
aswasif007 marked this pull request as ready for review July 28, 2026 13:58
The Rule 3 config cross-check read the plugin's config contract with a
substring regex over the raw, concatenated PHP source. A REQUIRED_FIELDS
or SENSITIVE_FIELDS mention inside a comment, or an unrelated constant
whose name merely ended in one of those, was taken as the real contract
and a conformant integration was reported non-conformant.

Strip PHP comments first, anchor on a real `const <NAME>` declaration,
and accept single- or double-quoted keys. Also match the manifest
placeholder as a whole token so a value that only embeds REPLACE_ME
isn't flagged.
scaffold.ts kept a private copy of the manifest filenames that had to
stay identical to the exported list in validate/manifest.ts or init and
validate would disagree on what a manifest is called. Import the one
source of truth instead.
@aswasif007
aswasif007 requested a review from pandah3 July 28, 2026 15:15
*/
function configFieldMismatches( ctx: Context, fields: Map< string, ManifestField > ): string[] {
const source = stripPhpComments( ctx.phpSource );
const required = phpConstStringArray( source, 'REQUIRED_FIELDS' );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This is minor, I think it's ok to not fix it for now.

Since we're concatenating the files, if we have this two files and the first one is loaded first, then we will miss the second required field (webhook_secret)

// inc/aaa-flags.php — unrelated class, scanned first
final class Flags {
    public const REQUIRED_FIELDS = [ 'api_base_url' ];
}
// inc/class-config.php — the real config contract
final class Config {
    public const CONSTANT_NAME = 'VIP_ACME_WIDGET_CONFIG';

    public const REQUIRED_FIELDS = [
        'api_base_url',
        'webhook_secret',
    ];
}

But I think it's fine. What we could probably shift is the way we communicate the validation. We're not actually 100% sure of the fields matching, so we could probably frame it slightly differently when the CLI returns the output/validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants