Skip to content

docs(rfc): add declarative artifact families and generation profiles - #1618

Open
MaoMengww wants to merge 4 commits into
oceanbase:masterfrom
MaoMengww:rfc/1424-declarative-families-and-generation-profiles
Open

MaoMengww wants to merge 4 commits into
oceanbase:masterfrom
MaoMengww:rfc/1424-declarative-families-and-generation-profiles

Conversation

@MaoMengww

Copy link
Copy Markdown
Contributor

Which issue or RFC does this PR close?

Refs #1424

Rationale for this change

Family identity is already a free string at the domain-value level (ArtifactRef.family), but every execution path keeps its own closed set
— artifact classes, authorization profiles, ID prefixes, processing bindings, contract enums — so changing the set of families requires
platform source and contract changes and "extend without forking" does not hold today. This RFC defines two governed extension points to
close that gap without executing extension code: what class of derived artifact is produced (declarative Artifact families), and how that
content is generated (Scope-owned generation profiles).

What changes are included in this PR?

  • Adds synchronized English and Chinese RFC documents.
  • Declarative Artifact families: a data-only extension package (powercontext.extension.json plus JSON Schema documents), closed manifest
    validation, fail-fast activation with per-family failure isolation, and no extension code on the production path.
  • Multi-version content schemas: several schema_versions per family, current_schema_version for new writes, the schema content marker
    as the version authority, and schema_version columns on pc_artifacts and pc_artifact_candidate_versions with RESTRICT composite
    foreign keys into the new pc_extension_families description table.
  • Content validation through thin wrapper types (RootModel[dict[str, Any]], ArtifactDraft/Artifact subclasses) reusing the existing
    strict decode seam, with the manifest schema as the only authority and document-scoped $ref resolution.
  • Fixed platform rules for retrieval projection and context rendering, plus projection rebuild on activation and upgrade.
  • Generation profiles: the built-in generation-profile family, immutable revisions, profile content model (target family, prompt
    reference, model catalog entry, bounded settings, output cap, empty-result field, failure policy), resolution keyed by profile key and
    frozen per operation.
  • Model catalog as server configuration, with the existing InferenceConfig.generation_* normalized into a default entry, and profile
    limits min'd against catalog bounds.
  • Generation provenance: a structured record plus a derived digest whose input contract is frozen by digest_input_version, covered by a
    new pc_artifact_generation_provenance table and candidate-side columns carried into Revision lineage at approval.
  • A generic POST /v1/generation/generate endpoint (profile-driven generation, or a manual proposal when only family is given), plus a
    read-only GET /v1/extensions discovery endpoint that makes default-deny explicable through four per-family states.
  • Registry-driven family dispatch replacing the closed family sets, contract changes (read-path family enums opened, write-path unions kept
    closed), and the deactivate/downgrade/reinstall state machine with historical readability from the family description table.
  • Author tools (extension init/validate/lock/diff) and administrator tools (extension enable/print-config,
    generation-profile), plus a config wizard step; validate performs structural lint and a skeleton dry run so an unconstrained schema
    cannot pass.
  • Documents drawbacks, alternatives, prior art, unresolved questions, and acceptance criteria covering external behavior.

Are there any user-facing changes?

No released behavior changes. This PR adds design documents only.

Design decisions worth calling out for reviewers:

  • The platform performs no content migration: historical Revisions are validated and rendered under the version each recorded.
  • Opening the family enums on read paths is an intentional breaking change for typed integrations when implemented, and must ship with make api-generate and make contract-test.
  • Not in the first slice: code-hook extension points, automatic triggering, tags and cross-Scope publication for extension families, and
    Dashboard presentation.

How was this change tested?

make docs-test: no issues.
uv run prek run --files ...: all hooks passed.

AI usage statement

Claude Code assisted me with research, design, and review.

@Teingi Teingi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The Family/Profile split and reuse of Candidate → Review → Revision make sense. I suggest resolving the four contract gaps below before implementation.

For S1, I would focus on one Runbook plus one generation profile, covering exact evidence → Candidate → human Review → retrieval/context contribution → exact reads after deactivation. The lock/diff tools, config wizard, and built-in family integration could follow separately.

I checked the wrapper/codec round trip and the target-version example against the repository on SQLite. These comments concern the proposed design; extension support itself is not implemented in this PR.

Comment thread docs/en/rfcs/1618_declarative_families_and_generation_profiles.md Outdated
Comment thread docs/en/rfcs/1618_declarative_families_and_generation_profiles.md Outdated
Comment thread docs/en/rfcs/1618_declarative_families_and_generation_profiles.md Outdated
Comment thread docs/en/rfcs/1618_declarative_families_and_generation_profiles.md Outdated
@MaoMengww

Copy link
Copy Markdown
Contributor Author

@Teingi Done. singleton target frozen at candidate creation (including the expected-absence state), provenance as a complete resolution-time snapshot with a frozen digest input contract, acceptance 2 split by domain as 2a–2d, one fixed recursive rule for array and nested-object rendering (acceptance 25–27), and Example 1 switched to an extension family — and built-in family integration moved to Future possibilities because its payoff is low (parameter tuning is already covered by deployment configuration and Prompt customization). Slices: S1 = one Runbook extension family + one generation profile; S2 = lock/diff, enable / print-config, the config wizard, and discovery-endpoint refinements

@Teingi Teingi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Rechecked at 751c82f1. The singleton target/expected-absence rule, recursive rendering, and built-in-family scope are now addressed. Two P2 contract gaps remain below. I replayed the CAS checks against ArtifactRepository on SQLite and verified the projection counterexample with SQLite FTS5. These are RFC design findings; extension support is not implemented by this PR.

| Table | Nature | Change |
| --- | --- | --- |
| `pc_artifact_generation_provenance` | **new** | Records Artifact Revision generation provenance by `(scope_id, family, artifact_id, revision)`: the profile reference and the structured generation provenance. Shaped like the existing `pc_artifact_publications`, with a composite foreign key into `pc_artifacts` on the reference columns. |
| `pc_extension_families` | **new** | Family description: primary key `(family, schema_version)`, storing that version's JSON Schema text, the source extension identifier, and the activation time, and recording the `prompt_templates[].id` and template text declared by that version's manifest; append-only, referenced by the artifact and candidate tables through `RESTRICT` composite foreign keys. It is what allows historical Revisions to be validated and rendered after deactivation, and it is what resolves generation provenance's template anchor, as well as `diff`'s authoritative input. |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Version template text independently of the content schema

Acceptance 2c permits changing a template under the same ID without changing the content schema, but this append-only table has only (family, schema_version) as its primary key. A template-only package upgrade therefore has no distinct row for the new text: inserting conflicts, overwriting loses the old template, and ignoring the conflict leaves the new template unavailable after uninstall. A stored digest cannot recover the missing text. Please retain immutable template snapshots keyed by a template digest or package version and bind provenance to that exact snapshot. Cover two package versions with the same schema and template ID but different text, with both texts recoverable after uninstall.


A declarative family cannot carry projection or rendering functions, so the platform decides both with **one fixed rule**, introducing no configurable dialect:

- **Projection**: traverse the content tree depth-first, take every string value, exclude the version marker `schema`, and concatenate them in a stable order consistent with payload normalization into searchable text; a newline boundary is inserted between array entries so a phrase query never matches across two array elements. This rule happens to reproduce the sample family's expected projection and adds no configuration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Define an actual element boundary for phrase matching

A newline does not provide this guarantee. Projecting steps = ["restart", "database"] as restart\ndatabase still matches the phrase "restart database" in SQLite FTS5 with the current unicode61 tokenizer; I reproduced this with both raw and analyzed projection text. The existing Analyzer also turns that newline into a space, and the current query compiler treats the words as OR terms. Thus the proposed projection cannot satisfy acceptance 26 while reusing the existing analysis/query path. Please specify how indexing and queries preserve array-element boundaries, or remove the cross-element phrase guarantee from the rule and acceptance criteria.

@MaoMengww

Copy link
Copy Markdown
Contributor Author

@Teingi Done:

  • Dropped the cross-element phrase guarantee
  • Template text now has its own version axis: pc_extension_prompt_templates keyed by template_digest, with provenance bound to it by a RESTRICT foreign key;

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