Skip to content

feat(spec): v0.7.4 — manifest extensions lane#9

Merged
tymofiy merged 3 commits into
mainfrom
dev
Apr 18, 2026
Merged

feat(spec): v0.7.4 — manifest extensions lane#9
tymofiy merged 3 commits into
mainfrom
dev

Conversation

@tymofiy
Copy link
Copy Markdown
Owner

@tymofiy tymofiy commented Apr 18, 2026

Summary

Adds an optional extensions object at the PACK.yaml manifest root as the sanctioned compatibility lane for experimental or implementation-specific metadata. The manifest root stays closed (additionalProperties: false); experimental fields belong under extensions, not at the top level.

Why

The spec currently has no sanctioned way to ship experimental manifest metadata without either:

  • breaking additionalProperties: false at the root (rejected — the closed root is load-bearing), or
  • promoting an unproven field into the core schema.

This PR introduces a narrow third path. Consumers MUST ignore unknown extension content. Extensions MUST NOT redefine core semantics. Tools can ship experiments without forcing a schema break or prematurely promoting a payload into the core standard.

Changed

  • spec/CHANGELOG.md — v0.7.4 entry (Added / Changed)
  • spec/CORE.md — Manifest Extensions prose + field table row + illustrative framing
  • spec/SPEC.md — new §3.2 Manifest Extensions section + YAML example
  • conformance/grammar/kp-pack.schema.jsonextensions property; root remains closed

Illustrative example

The spec uses one payload to make the lane concrete:

extensions:
  ai_brief:
    version: 1
    verdict: acceptable
    headline: "Strong base attribution, but provenance gap remains"

The spec explicitly frames this as illustrative only — extension names and shapes are defined by their producers, not by KP:1.

Judgment call — ai_brief as the public example

Whether to keep ai_brief (a real internal concept already consumed by the viewer) or invent a generic placeholder was consulted across two independent models. Split opinion:

  • One position: invent a placeholder, cite RFC 6648 / Hyrum's Law — third parties will mirror the shape regardless of disclaimer.
  • Other position: keep it with explicit "illustration only" framing, cite OpenAPI vendor-extension precedent where real examples + registry/disclaimer is the canonical pattern.

Decision: keep ai_brief, but strengthen the "illustrative only, producer-defined" framing in both CORE.md prose and SPEC.md example comment. This threads the dissent without losing the motivating concreteness.

Section numbering

Initial pass placed Manifest Extensions at §3.1, which pushed Channels to §3.2 and invalidated two existing §3.1 cross-references in SPEC.md (lines 227 and 1329). Corrected by placing Manifest Extensions at §3.2 instead, so Channels keeps §3.1 and cross-references stay valid.

Downstream impact — verified

  • kp-viewer (PackLoader.swift:142–193, 172–177, 211–213) — already parses extensions.ai_brief and ignores unknown top-level fields. v0.7.4 describes what the viewer already consumes. No viewer code change required.
  • kp-forge (serialize.ts:1181, types.ts:443, assemble.ts:88) — already emits extensions.ai_brief. No sealer change required.
  • kp-packs relay — doesn't touch the extensions surface. Transparent.
  • intel / providers — doesn't touch manifest schema. Transparent.
  • Existing packs in repos/packs — all 54 manifests validate against the updated schema. Zero migration.

In other words: v0.7.4 is the spec catching up to what the tooling already produces. No coordinated downstream rollout is required.

Verified locally

  • lefthook run pre-commit — all rules pass
  • python3 conformance/run.py — 12/12 pass
  • markdownlint '**/*.md' — clean
  • Cross-refs (§3.1 Channels still resolves; Extensions is §3.2)

tymofiy and others added 2 commits April 18, 2026 07:41
Three strings in the public spec matched the hook's patterns added
in ca94d5b. The hook checks full file contents of staged files, so
these pre-existing strings blocked any commit touching the files:

- conformance/grammar/kp-pack.schema.json:149 — field description
  in provenance schema.
- spec/SPEC.md:252 — YAML comment in the manifest example.
- spec/SPEC.md:777 — evidence example prose.

First two were false positives from the role-word regex (matched any
letter after the role word, triggering on generic prose). Slight
rewording avoids the false positive without changing semantics.

Third used phrasing reserved for internal process notes. Reworded to
generic aggregation language appropriate for a public example.

Also tighten the hook's role-word regex from [A-Z0-9] (over-broad)
to [0-9]+\b (numeric attribution only, which is the intended target).
Same change applied to pre-commit and commit-msg hooks.

Co-Authored-By: Claude <noreply@anthropic.com>
Adds an optional `extensions` object at the PACK.yaml manifest root
as the sanctioned lane for experimental or implementation-specific
metadata. The manifest root stays closed (additionalProperties: false);
new fields belong under `extensions`, not at the top level.

Consumers MUST ignore unknown extension content. Extensions MUST NOT
redefine core KP semantics. Extension names and shapes are defined by
their producers, not by KP:1 — the public spec shows `ai_brief` as
one illustrative example, not as a standardized payload.

Updated:
- CHANGELOG.md — v0.7.4 entry (Added / Changed)
- CORE.md — Manifest Extensions prose + field table row
- SPEC.md — §3.2 Manifest Extensions + example usage in the YAML demo
- kp-pack.schema.json — `extensions` as allowed top-level object,
  still closed at the root via additionalProperties: false

Co-Authored-By: Claude <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 18, 2026 11:44
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a sanctioned “manifest extensions lane” to KP:1 by introducing an optional extensions object at the PACK.yaml root, preserving a closed manifest root (additionalProperties: false) while enabling experimental/implementation-specific metadata.

Changes:

  • Adds extensions guidance + examples to the spec docs (CORE.md, SPEC.md) and records the change in the changelog (v0.7.4).
  • Extends the normative PACK.yaml JSON Schema to allow an extensions object while keeping the root closed.
  • Tightens lefthook deny-list regexes (stacked from #8).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
spec/SPEC.md Documents the extensions lane and adds an illustrative manifest example + new §3.2 section.
spec/CORE.md Adds extensions to the Core Optional Fields table and provides normative guidance + examples.
spec/CHANGELOG.md Adds v0.7.4 entry describing the manifest extensions lane.
lefthook.yml Updates deny-list grep patterns (process-language detection).
conformance/grammar/kp-pack.schema.json Adds extensions as an allowed top-level object; keeps root additionalProperties: false.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lefthook.yml

# Process language (the patterns that actually leaked)
if grep -inE 'cross-model (review|consultation|spec review)|multi-model (synthesis|analysis|consultation|spec review)|three-model consultation|two-model consultation|round [0-9]+ (review|verify|cross-model|findings)|consulted (codex|gemini|claude)|adversarial review|(codex|gemini|claude) feedback|reviewer [A-Z0-9]|session handover|model attributions' "$file" 2>/dev/null; then
if grep -inE 'cross-model (review|consultation|spec review)|multi-model (synthesis|analysis|consultation|spec review)|three-model consultation|two-model consultation|round [0-9]+ (review|verify|cross-model|findings)|consulted (codex|gemini|claude)|adversarial review|(codex|gemini|claude) feedback|reviewer [0-9]+\b|session handover|model attributions' "$file" 2>/dev/null; then
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

The pattern reviewer [0-9]+\b is using \b as a word-boundary, but grep -E does not portably support \b as a word-boundary (often treated as backspace). This can make the deny-list miss matches like reviewer 12 on some environments. Use a POSIX-compatible boundary (e.g., reviewer [0-9]+([^0-9]|$)) or switch to grep -P if you want \b semantics.

Suggested change
if grep -inE 'cross-model (review|consultation|spec review)|multi-model (synthesis|analysis|consultation|spec review)|three-model consultation|two-model consultation|round [0-9]+ (review|verify|cross-model|findings)|consulted (codex|gemini|claude)|adversarial review|(codex|gemini|claude) feedback|reviewer [0-9]+\b|session handover|model attributions' "$file" 2>/dev/null; then
if grep -inE 'cross-model (review|consultation|spec review)|multi-model (synthesis|analysis|consultation|spec review)|three-model consultation|two-model consultation|round [0-9]+ (review|verify|cross-model|findings)|consulted (codex|gemini|claude)|adversarial review|(codex|gemini|claude) feedback|reviewer [0-9]+([^0-9]|$)|session handover|model attributions' "$file" 2>/dev/null; then

Copilot uses AI. Check for mistakes.
Comment thread lefthook.yml
clean=$(echo "$msg" | sed -E '/^Co-Authored-By: (Claude|Codex|Gemini|Antigravity|Cursor) <noreply@[^>]+>$/d')

if echo "$clean" | grep -iE 'cross-model|multi-model (synthesis|analysis|consultation|review)|round [0-9]+ (review|verify|findings)|consulted (codex|gemini|claude)|(codex|gemini|claude) (feedback|suggested|reviewed)|adversarial review|reviewer [A-Z0-9]|session handover|model attributions' >/dev/null 2>&1; then
if echo "$clean" | grep -iE 'cross-model|multi-model (synthesis|analysis|consultation|review)|round [0-9]+ (review|verify|findings)|consulted (codex|gemini|claude)|(codex|gemini|claude) (feedback|suggested|reviewed)|adversarial review|reviewer [0-9]+\b|session handover|model attributions' >/dev/null 2>&1; then
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

Same issue as pre-commit: grep -iE with reviewer [0-9]+\b is not portable because \b isn't reliably a word-boundary in ERE. This can weaken the commit-msg deny-list (false negatives). Prefer a POSIX-safe boundary like reviewer [0-9]+([^0-9]|$) or use grep -P if PCRE is acceptable.

Suggested change
if echo "$clean" | grep -iE 'cross-model|multi-model (synthesis|analysis|consultation|review)|round [0-9]+ (review|verify|findings)|consulted (codex|gemini|claude)|(codex|gemini|claude) (feedback|suggested|reviewed)|adversarial review|reviewer [0-9]+\b|session handover|model attributions' >/dev/null 2>&1; then
if echo "$clean" | grep -iE 'cross-model|multi-model (synthesis|analysis|consultation|review)|round [0-9]+ (review|verify|findings)|consulted (codex|gemini|claude)|(codex|gemini|claude) (feedback|suggested|reviewed)|adversarial review|reviewer [0-9]+([^0-9]|$)|session handover|model attributions' >/dev/null 2>&1; then

Copilot uses AI. Check for mistakes.
Comment on lines +390 to 394
"extensions": {
"type": "object",
"additionalProperties": true,
"description": "Extension lane for experimental or implementation-specific manifest metadata. Consumers MUST ignore unrecognized extension content."
}
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

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

extensions is now part of the normative schema, but none of the conformance fixtures currently exercise it (including valid/maximal.kpack, which is documented as covering every optional PACK.yaml field). Add an extensions object to the maximal fixture (and optionally an invalid fixture where extensions is non-object) to keep schema coverage claims accurate and prevent regressions.

Copilot uses AI. Check for mistakes.
@tymofiy tymofiy merged commit bde8674 into main Apr 18, 2026
1 check passed
tymofiy added a commit that referenced this pull request May 26, 2026
Adds two layers of defense against real-engagement names landing in
this public repository's prose, YAML samples, or pack identifiers
(continuation of the 91d5e27 / c6c6167 / f4365c6 de-leak series).

Layer 1 — agent awareness (primary):
  AGENTS.md gains a 9th MUST NOT rule covering real client / collection
  / vendor / family names. Uses only fictional placeholders in the rule
  text so the file itself never names a real engagement.

Layer 2 — mechanical backstop:
  lefthook pre-commit and commit-msg hooks gain a `client-names` step
  that scans staged content and commit messages against patterns loaded
  from $DENY_PATTERNS_CLIENT_NAMES.

The patterns themselves live in a gitignored .private-deny-list file
sourced by .lefthookrc (already loaded for PATH setup). A committed
.private-deny-list.example documents the shape. Fresh clones without
a local patterns file get only the behavioral defense in AGENTS.md —
acceptable trade-off, since putting the actual names in the public
hook config would defeat the scrub.

Files:
  - .gitignore                   ignore .private-deny-list
  - .lefthookrc                  source .private-deny-list if present
  - .private-deny-list.example   shape doc with placeholder names
  - lefthook.yml                 add client-names step to pre-commit + commit-msg
  - AGENTS.md                    add MUST NOT #9

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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