Skip to content

refactor(artifacts)!: establish the shared Kind contract (FACT-61) - #535

Merged
chris-schra merged 1 commit into
developfrom
fw-sync/7d2c184
Sep 8, 2026
Merged

chris-schra merged 1 commit into
developfrom
fw-sync/7d2c184

Conversation

@makaioai

@makaioai makaioai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Refactors Artifact Kind definitions into one shared, validated contract: every Kind declares its category, readable title path and positive integer schema generation. Existing framework and product consumers migrate together; old metadata no longer silently controls validation, rendering, context selection or status transitions.

Tracks FACT-61, under FACT-58. Consumer PR: Factory makaio-ai/makaio#929.

Contract and migration

  • Require category, titlePath, numeric schemaVersion, description and a data schema. Validate data-relative paths and the declared relation, uniqueness and evidence constraints structurally.
  • Preserve live-only hooks. New declarative constraints do not introduce a lifecycle or cross-Artifact uniqueness engine.
  • Remove Kind scopeSchema, observationSchema, discriminator, conflictPolicy, status, lifecycle, projection and defaultContext. Explicit caller context selectors and custom view builders remain available.
  • Carry integer generations through registration, revisions, workflow bindings, hooks, MCP and product persistence. Existing TEXT storage uses an explicit strict codec; historical opaque/SemVer values are not guessed or rewritten.
  • Allow a caller-assigned create identity. Existing primary-key/CAS mechanisms reject collisions without overwrite or duplicate creation events. This preserves retry identity independently of semantic uniqueness.

Deliberate scope and temporary losses

This is a pre-production contract cut, not a replacement of every retired capability. Generic Kind-driven field/summary rendering, surface permission/affordance routing, implicit related-context injection, derived Kind-status events/readiness and automatic natural-key conflict handling are retired. Explicit custom rendering, caller-selected context and existing Workpiece paths remain. Unsupported legacy activation must fail visibly.

Reusable Kind views and their shared extensible vocabulary remain a later slice. Semantic uniqueness execution is tracked in FACT-103. Configurable Confluence representations are FACT-65; the entire existing World Plan is Legacy, with a possible separate Epic recorded in FACT-104.

Implementation decisions to review

  • Lifecycle tokens in declaration validation are implementation choices for this cut, not a claim that every name was explicitly agreed: Knowledge valid/retired, Commitment proposed/decided/fulfilled/revoked, Interaction open/resolved/closed-without-resolution; Records reject lifecycle-conditioned declarations.

  • No migration engine or historical-content conversion is introduced. Incompatible old generations fail visibly.

  • Technical scope/identity boundaries remain distinct from semantic relations. Category is generic Core vocabulary; no product Kind names are added to the shared engine.

  • Caller-assigned identity addresses technical replay; it neither implements uniqueness nor decides whether semantic duplicates should merge.

  • Authoring fails visibly for closed-object intersections and Zod tuples whose current serialization cannot preserve their live constraints. This cut does not introduce a schema-normalization engine; ordinary object/union Kinds remain supported. Standard hand-authored JSON Schemas are validated according to their declared dialect and constraints.

Review hardening

  • Preserve canonical cross-field validation at inline Factory configuration intake and reject retired GitHub field inference/derived modes before provisioning.
  • Inspect shared and referenced union constraints according to the declared schema dialect. Unsupported dialects are rejected at registration rather than failing every write later. Path inspection checks declared locations/types; it does not prove global schema satisfiability. The original complete schema still validates every write.
  • Skip blank generated extraction entries without abandoning later valid observations; give attachment Artifacts a readable producer-owned label when supplied names are blank.
  • Use a stable UUID operation identity for the first review-orchestration snapshot. Concurrent creators recompute through the existing CAS loop; historical identities remain intact. Report-local finding replay remains separate from semantic cross-report consolidation.
  • Repair a verified process-cleanup classification race exposed by validation: TERM/escalation/final cleanup/probe EPERM may proceed to bounded quiescence verification, but never grants success by itself. Safe release still requires an absent group or positively observed zombie-only members; live or unverifiable groups fail closed. No timeout or TERM/escalation policy is relaxed.

Additional confirmed review corrections:

  • Reject asynchronous schemas at registration and compiled async validators before invocation; named anchors are explicitly unsupported in this cut. Zod 4 already enforces safe integer generations, now covered by a boundary regression.
  • Index primitive leaves within explicitly declared searchable object containers without indexing their keys or undeclared siblings.
  • Observe status only when an explicit workflow binding supplies request-only statusPath. Persisted post-hook values determine existing status events; the status hook sees the latest revision after earlier hooks. No Kind status inference returns.
  • Terminally supersede stale legacy GitHub projection commands using exact-slot revision/checksum checks. Retain provider identity and uncertain-create evidence, allow safe explicit preparation, and preserve matching prepared-command recovery. Migration 0005 changes only the recovery index; no table rewrite or new routing engine.

Scoped review decision

For this PR only, the maintainer requires fixing all valid findings when a review round contains a merge blocker. A round containing only non-blocking findings is recorded for a prompt post-merge follow-up, without another implementation commit here.

The late Codex round was initially deferred, then the final same-head CI added a blocker. Under the mixed-round rule, its valid corrections are included together; FACT-61 comment 10484 records that disposition. The earlier attached patch remains a draft historical snapshot, not the final implementation.

  • Registration uses an explicit fragment-only schema-reference profile. External/document-relative references and missing/non-schema fragment targets fail early, including unrelated optional properties. Owned non-string $ref values fail; example/default/constant/enum data is untouched. Boolean and recursive schema targets remain supported. Absolute self-contained $id forms, percent-encoded URI fragments and paths through intermediate arrays are outside this cut's profile even where AJV could support them; no new schema resolver is introduced.
  • The retained blueprint materializer forwards its configured status position as a data-relative pointer. Existing actual-value comparison suppresses unchanged status events, including relation-only changes. No Kind status inference returns.
  • Workflow creation requires explicit initial data. A binding without a create expression remains valid when an existing Artifact reference is supplied or resolved; invalid creation no longer synthesizes {}.

Validation and delivery

Current head: 75b9d673e0e077fda670da14a76bd2995731b84a. full yarn validate passed 11,016 files. The complete supported MAKAIO_TEST_PLAN=bounded yarn test plan passed on Node 22.22.2 / Bun 1.4.2 with 30,438 Vitest tests, 68 skipped, plus 25 Bun tests (330.1 seconds). Every project and the execution-sensitive lanes are included. Independent reviews of the schema reference, workflow binding and explicit status corrections are clean. CodeRabbit reviewed all eight changed files, including both new regression files, with zero findings.

The CI test matrix now pins Bun 1.4.2, matching the runtime used by the successful same-head distribution build. The existing child-process deadlines, full declaration backend and runtime assertions are unchanged. The complete CI run 34267280415 passed on this exact head, including both installed-consumer proofs. The previous failure was: run 34262513930 hit both installed-consumer builds' own 270-second deadlines under Bun 1.3.14. The earlier aggregate setup correction remains necessary: deadlines are derived from the existing sequential child limits (recovery 630 seconds plus five seconds hook headroom; local Git 510 plus five).

Runtime evidence has distinct limits. The official Bun makaio-ai/makaio#33102 symlink/repeated-build fixture fails on 1.3.14 and passes on 1.4.2 locally, but our distribution build uses tsdown rather than direct Bun.build. The successful standalone job also installs fresh dependencies without a copied lockfile, unlike the locked full-workspace fixture. Therefore neither observation alone establishes the cause of the CI timing gap.

A local negative control on Node 24.12.0 / Bun 1.4.2 produced 26 framework-platform/adapter failures involving spawn EBADF and worker startup, with 30,412 tests passing. Keeping Bun and the source tree unchanged, the complete Node 22 run passed. Both results are retained in FACT-61 and shared with FACT-102; no claim is made that the local Darwin failure and Linux CI timeout share one cause.

The framework archive from 75b9d673e0e077fda670da14a76bd2995731b84a has SHA256 5607a7836600842a7c4aa627b9db670b3f908e12c45ef583d8e6483b5e446849. The private-facade archive has SHA256 617a685f19dcc920409d94043531011d50a6da76b2a8ef46f065d99dd908169f; all 249 files were verified byte-for-byte and 43 private-package tests passed. These are local integration archives, not npm publications. These archives include the current schema-reference and workflow-binding corrections. Independent verification matched all 678 framework files and 249 private files against the installed/vendored copies.

Factory makaio-ai/makaio#929 passed its complete local canon against those archives: static validation (2,800 files), 4,685 Bun tests, 7,802 Vitest tests (seven skipped), TypeScript, build and real PostgreSQL/server/CLI/MCP/dashboard/auth E2E. Its clean-install CI remains blocked by the committed old published framework until actual publication and pin update.

Delivery requires a new @makaio/framework publication after upstream merge/sync and a refreshed private @makaio/cyberport-factory bundle. No new @makaio/storage-pg release is needed: its implementation is unchanged and shared helpers are external framework imports. No deployment, merge, publication or database reset is included. The exact-head CI remains green. Delayed Codex feedback reopened review after the initial 20-minute observation; the maintainer extended final observation to 40 minutes, now running on this unchanged head. The three valid non-blocking items below are explicitly assigned to the prompt post-merge follow-up. The Factory consumer still requires the ensuing framework publication and pin update.

Delayed review: non-blocking follow-up

FACT-61 comment 10524 assigns all three independently verified findings to the first upstream follow-up promptly after merge, under the maintainer's scoped rule. No current-release blocker was found.

  • Validate complete dialect-specific schema validity before authoritative registration, including batch replacement. Malformed optional keywords currently pass registration but cause visible compilation failures on writes. No shipped Kind triggers this.
  • Accept valid implicit root-object schemas using the Artifact data envelope's object guarantee. Preserve correct rejection of nested schemas that can still admit scalar values; do not globally infer object type from properties.
  • Include managed Artifact display titles in searchableFields, with a focused FTS regression. Paste creation, list/read and content search work, but name-based API/tool discovery misses the separately stored title. Existing registration-signature handling can rebuild derived search data.

Synced-from: makaio-ai/makaio@7d2c1842365e5ca1419eaa97152394308421c0ab

…1297)

Refactors Artifact Kind definitions into one shared, validated contract:
every Kind declares its category, readable title path and positive
integer schema generation. Existing framework and product consumers
migrate together; old metadata no longer silently controls validation,
rendering, context selection or status transitions.

Tracks [FACT-61](https://makaio.atlassian.net/browse/FACT-61), under
[FACT-58](https://makaio.atlassian.net/browse/FACT-58). Consumer PR:
[Factory #929](https://github.com/computeruniverse/ai-factory/pull/929).

## Contract and migration

- Require `category`, `titlePath`, numeric `schemaVersion`, description
and a data schema. Validate data-relative paths and the declared
relation, uniqueness and evidence constraints structurally.
- Preserve live-only hooks. New declarative constraints do not introduce
a lifecycle or cross-Artifact uniqueness engine.
- Remove Kind `scopeSchema`, `observationSchema`, `discriminator`,
`conflictPolicy`, `status`, `lifecycle`, `projection` and
`defaultContext`. Explicit caller context selectors and custom view
builders remain available.
- Carry integer generations through registration, revisions, workflow
bindings, hooks, MCP and product persistence. Existing TEXT storage uses
an explicit strict codec; historical opaque/SemVer values are not
guessed or rewritten.
- Allow a caller-assigned create identity. Existing primary-key/CAS
mechanisms reject collisions without overwrite or duplicate creation
events. This preserves retry identity independently of semantic
uniqueness.

## Deliberate scope and temporary losses

This is a pre-production contract cut, not a replacement of every
retired capability. Generic Kind-driven field/summary rendering, surface
permission/affordance routing, implicit related-context injection,
derived Kind-status events/readiness and automatic natural-key conflict
handling are retired. Explicit custom rendering, caller-selected context
and existing Workpiece paths remain. Unsupported legacy activation must
fail visibly.

Reusable Kind views and their shared extensible vocabulary remain a
later slice. Semantic uniqueness execution is tracked in
[FACT-103](https://makaio.atlassian.net/browse/FACT-103). Configurable
Confluence representations are
[FACT-65](https://makaio.atlassian.net/browse/FACT-65); the entire
existing World Plan is Legacy, with a possible separate Epic recorded in
[FACT-104](https://makaio.atlassian.net/browse/FACT-104).

## Implementation decisions to review

- Lifecycle tokens in declaration validation are implementation choices
for this cut, not a claim that every name was explicitly agreed:
Knowledge `valid/retired`, Commitment
`proposed/decided/fulfilled/revoked`, Interaction
`open/resolved/closed-without-resolution`; Records reject
lifecycle-conditioned declarations.
- No migration engine or historical-content conversion is introduced.
Incompatible old generations fail visibly.
- Technical scope/identity boundaries remain distinct from semantic
relations. Category is generic Core vocabulary; no product Kind names
are added to the shared engine.
- Caller-assigned identity addresses technical replay; it neither
implements `uniqueness` nor decides whether semantic duplicates should
merge.

- Authoring fails visibly for closed-object intersections and Zod tuples
whose current serialization cannot preserve their live constraints. This
cut does not introduce a schema-normalization engine; ordinary
object/union Kinds remain supported. Standard hand-authored JSON Schemas
are validated according to their declared dialect and constraints.

## Review hardening

- Preserve canonical cross-field validation at inline Factory
configuration intake and reject retired GitHub field inference/derived
modes before provisioning.
- Inspect shared and referenced union constraints according to the
declared schema dialect. Unsupported dialects are rejected at
registration rather than failing every write later. Path inspection
checks declared locations/types; it does not prove global schema
satisfiability. The original complete schema still validates every
write.
- Skip blank generated extraction entries without abandoning later valid
observations; give attachment Artifacts a readable producer-owned label
when supplied names are blank.
- Use a stable UUID operation identity for the first
review-orchestration snapshot. Concurrent creators recompute through the
existing CAS loop; historical identities remain intact. Report-local
finding replay remains separate from semantic cross-report
consolidation.
- Repair a verified process-cleanup classification race exposed by
validation: TERM/escalation/final cleanup/probe `EPERM` may proceed to
bounded quiescence verification, but never grants success by itself.
Safe release still requires an absent group or positively observed
zombie-only members; live or unverifiable groups fail closed. No timeout
or TERM/escalation policy is relaxed.

Additional confirmed review corrections:

- Reject asynchronous schemas at registration and compiled async
validators before invocation; named anchors are explicitly unsupported
in this cut. Zod 4 already enforces safe integer generations, now
covered by a boundary regression.
- Index primitive leaves within explicitly declared searchable object
containers without indexing their keys or undeclared siblings.
- Observe status only when an explicit workflow binding supplies
request-only `statusPath`. Persisted post-hook values determine existing
status events; the status hook sees the latest revision after earlier
hooks. No Kind status inference returns.
- Terminally supersede stale legacy GitHub projection commands using
exact-slot revision/checksum checks. Retain provider identity and
uncertain-create evidence, allow safe explicit preparation, and preserve
matching prepared-command recovery. Migration 0005 changes only the
recovery index; no table rewrite or new routing engine.

## Scoped review decision

For this PR only, the maintainer requires fixing all valid findings when
a review round contains a merge blocker. A round containing only
non-blocking findings is recorded for a prompt post-merge follow-up,
without another implementation commit here.

The late Codex round was initially deferred, then the final same-head CI
added a blocker. Under the mixed-round rule, its valid corrections are
included together; [FACT-61 comment
10484](https://makaio.atlassian.net/browse/FACT-61?focusedCommentId=10484)
records that disposition. The earlier attached patch remains a draft
historical snapshot, not the final implementation.

- Registration uses an explicit fragment-only schema-reference profile.
External/document-relative references and missing/non-schema fragment
targets fail early, including unrelated optional properties. Owned
non-string `$ref` values fail; example/default/constant/enum data is
untouched. Boolean and recursive schema targets remain supported.
Absolute self-contained `$id` forms, percent-encoded URI fragments and
paths through intermediate arrays are outside this cut's profile even
where AJV could support them; no new schema resolver is introduced.
- The retained blueprint materializer forwards its configured status
position as a data-relative pointer. Existing actual-value comparison
suppresses unchanged status events, including relation-only changes. No
Kind status inference returns.
- Workflow creation requires explicit initial data. A binding without a
create expression remains valid when an existing Artifact reference is
supplied or resolved; invalid creation no longer synthesizes `{}`.

## Validation and delivery

Current head: `75b9d673e0e077fda670da14a76bd2995731b84a`. full `yarn
validate` passed **11,016 files**. The complete supported
`MAKAIO_TEST_PLAN=bounded yarn test` plan passed on **Node 22.22.2 / Bun
1.4.2** with **30,438 Vitest tests, 68 skipped, plus 25 Bun tests**
(330.1 seconds). Every project and the execution-sensitive lanes are
included. Independent reviews of the schema reference, workflow binding
and explicit status corrections are clean. CodeRabbit reviewed all eight
changed files, including both new regression files, with zero findings.

The CI test matrix now pins Bun **1.4.2**, matching the runtime used by
the successful same-head distribution build. The existing child-process
deadlines, full declaration backend and runtime assertions are
unchanged. The complete [CI run
34267280415](https://github.com/makaio-ai/makaio/actions/runs/34267280415)
passed on this exact head, including both installed-consumer proofs. The
previous failure was: [run
34262513930](https://github.com/makaio-ai/makaio/actions/runs/34262513930)
hit both installed-consumer builds' own 270-second deadlines under Bun
1.3.14. The earlier aggregate setup correction remains necessary:
deadlines are derived from the existing sequential child limits
(recovery 630 seconds plus five seconds hook headroom; local Git 510
plus five).

Runtime evidence has distinct limits. The official [Bun
#33102](oven-sh/bun#33102)
symlink/repeated-build fixture fails on 1.3.14 and passes on 1.4.2
locally, but our distribution build uses tsdown rather than direct
`Bun.build`. The successful standalone job also installs fresh
dependencies without a copied lockfile, unlike the locked full-workspace
fixture. Therefore neither observation alone establishes the cause of
the CI timing gap.

A local negative control on Node 24.12.0 / Bun 1.4.2 produced 26
framework-platform/adapter failures involving spawn `EBADF` and worker
startup, with 30,412 tests passing. Keeping Bun and the source tree
unchanged, the complete Node 22 run passed. Both results are retained in
FACT-61 and shared with FACT-102; no claim is made that the local Darwin
failure and Linux CI timeout share one cause.

The framework archive from `75b9d673e0e077fda670da14a76bd2995731b84a`
has SHA256
`5607a7836600842a7c4aa627b9db670b3f908e12c45ef583d8e6483b5e446849`. The
private-facade archive has SHA256
`617a685f19dcc920409d94043531011d50a6da76b2a8ef46f065d99dd908169f`; all
249 files were verified byte-for-byte and 43 private-package tests
passed. These are local integration archives, not npm publications.
These archives include the current schema-reference and workflow-binding
corrections. Independent verification matched all 678 framework files
and 249 private files against the installed/vendored copies.

Factory #929 passed its complete local canon against those archives:
static validation (2,800 files), 4,685 Bun tests, 7,802 Vitest tests
(seven skipped), TypeScript, build and real
PostgreSQL/server/CLI/MCP/dashboard/auth E2E. Its clean-install CI
remains blocked by the committed old published framework until actual
publication and pin update.

Delivery requires a new `@makaio/framework` publication after upstream
merge/sync and a refreshed private `@makaio/cyberport-factory` bundle.
No new `@makaio/storage-pg` release is needed: its implementation is
unchanged and shared helpers are external framework imports. No
deployment, merge, publication or database reset is included. The
exact-head CI and final 20-minute review observation are complete: no
new actionable feedback arrived. The upstream PR is ready for maintainer
merge; the Factory consumer still requires the ensuing framework
publication and pin update.

Synced-from: makaio-ai/makaio@7d2c1842365e5ca1419eaa97152394308421c0ab
@chris-schra
chris-schra merged commit 3f534f3 into develop Sep 8, 2026
22 checks passed
@chris-schra
chris-schra deleted the fw-sync/7d2c184 branch September 8, 2026 19:52

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b503c180af

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

return combined ? fieldSchemas(root, combined, parts, required, refs) : undefined;
}
if (parts.length === 0) return [node];
if (node.type !== 'object') return undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Accept implicit root-object JSON Schemas

Treat the root artifact data envelope as an object when inspecting paths. A valid hand-authored schema such as { properties: { title: { type: 'string' } }, required: ['title'] } omits the optional type keyword, but artifact data is already constrained to an object by ArtifactRevisionSchema; this unconditional check therefore rejects registrations whose title is correctly required for every possible artifact payload.

Useful? React with 👍 / 👎.

Comment on lines +67 to +70
schemaVersion: ArtifactSchemaVersionSchema,
category: ArtifactCategorySchema,
dataSchema: JsonObjectContractSchema,
titlePath: ArtifactDataPathSchema,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update the public artifact authoring documentation

Update the user-facing examples with this contract change. docs/creating-extensions.md:425-511 still instructs users to pass string schema versions and the removed conflictPolicy, projection, and defaultContext APIs, while docs/creating-workflows.md:137-142 and 411-416 still use schemaVersion: '1'; copying these examples now produces type errors or registration failures against the newly required numeric version, category, and title path.

Useful? React with 👍 / 👎.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant