Skip to content

feat: define runtime state schema#230

Merged
devkade merged 1 commit into
devfrom
feat/issue-185-runstate-schema
May 18, 2026
Merged

feat: define runtime state schema#230
devkade merged 1 commit into
devfrom
feat/issue-185-runstate-schema

Conversation

@devkade
Copy link
Copy Markdown
Owner

@devkade devkade commented May 17, 2026

Summary

  • Adds a versioned RuntimeState schema for the objective-driven learning runtime.
  • Defines typed schema boundaries for RunObjective, PolicySelection, runtime tasks, worker state, evidence/artifact refs, evaluation results, reward records, and integration candidates.
  • Adds fail-closed parsing for malformed top-level and nested state, invalid enum values, invalid artifact refs, and unknown newer schema versions.
  • Adds RunContract-facing runtime artifact refs for objective, policy-selection, and evaluation artifacts.
  • Documents the runtime state versioning boundary in the README.

Linked issue

Closes #185
Refs #167

Problem

The objective-driven learning runtime roadmap needs a concrete state contract before event replay, worker execution, repair, and reward loops can safely build on it. Without a versioned schema and compatibility policy, later runtime slices could persist incompatible state or let unknown newer data be interpreted optimistically.

Options considered

  1. Keep Design: define RunState schemas, versions, and migration policy #185 as documentation-only.
    • Pros: smallest patch.
    • Cons: no executable schema or fail-closed compatibility check.
  2. Import the broader runtime state/event spine from PR feat: add runtime state event spine #227.
  3. Add a narrow typed schema plus parser and focused tests.

Selected approach

  • Selected option: narrow typed schema plus fail-closed parser.
  • Why this one: it gives later runtime phases an executable state boundary while staying under the review-size gate.
  • Risks/trade-offs: this does not implement an event store, runtime execution, or storage migration.

Implementation by file/surface

  • src/domain/runtime-state.ts
    • Defines RuntimeState.schemaVersion: 1 and runtime schema interfaces.
    • Adds createRuntimeState, parseRuntimeState, and buildRunContractRuntimeRefs.
    • Fails closed for unknown newer schema versions, invalid local schema versions, malformed timestamps, invalid enum values, malformed nested records, and invalid artifact refs.
  • test/runtime-state.test.ts
    • Covers initialization, parsing, unknown-newer-version rejection, malformed refs, RunContract-facing refs, and success/repair-required examples.
  • README.md
    • Documents the runtime state versioning and RunContract artifact reference boundary.

Why this fixes it

#185 asks for schema list, version/migration policy, RunContract-to-runtime artifact refs, unknown newer schema behavior, and backward compatibility expectations. This PR encodes those as a versioned additive schema with a parser that rejects unsupported newer versions rather than guessing.

QA / Verification

  • npm ci — pass
  • npx tsx --test test/runtime-state.test.ts — pass, 4 tests
  • npm run check — pass
  • npm run check:unused — pass
  • npm run quality:budgets — pass with existing non-failing warning: code_smells=55 > 20; coverage not configured
  • npm run verify — pass, 509 passed / 11 skipped; same existing non-failing quality warning
  • git diff --check — pass

Anomalies observed

Risks / Follow-up

kapi-agent review expectations and current-head merge gate

  • Expected focus: schema/versioning completeness for Design: define RunState schemas, versions, and migration policy #185, fail-closed compatibility behavior, RunContract artifact-ref boundary, and no GitHub/Ragna/kapi-agent semantics in core.
  • Merge gate: require current-head kapi-agent approval and successful kapi-agent/review check before merge.

@devkade
Copy link
Copy Markdown
Owner Author

devkade commented May 17, 2026

@kapi-agent review

Revision explanation for current head d9d9f5be009ad4f33f6b3c0ec26ea3b518956677:

What changed:

  • Added a versioned RuntimeState schema and related runtime artifact/task/worker/evaluation/reward/integration candidate types.
  • Added fail-closed parsing for malformed state and unknown newer schema versions.
  • Added focused runtime state tests and README boundary documentation.

Why this closes the prior feedback:

Verification:

  • npm ci — pass
  • npx tsx --test test/runtime-state.test.ts — pass
  • npm run check — pass
  • npm run check:unused — pass
  • npm run quality:budgets — pass with existing non-failing code_smells warning
  • npm run verify — pass, 509 passed / 11 skipped
  • git diff --check — pass

@kapi-agent
Copy link
Copy Markdown

kapi-agent Bot commented May 17, 2026

kapi-agent review completed

The formal GitHub PR review and required check were submitted separately. This request comment is kept concise to avoid duplicating the full review body.

kapi-agent request lifecycle:

  • Status: COMPLETED
  • Head: d9d9f5be009a
  • Formal review event: REQUEST_CHANGES
  • Review API status: 200
  • Required check API status: 201

Copy link
Copy Markdown

@kapi-agent kapi-agent Bot left a comment

Choose a reason for hiding this comment

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

kapi-agent review

Verdict: REQUEST_CHANGES

Blocking issues

  • src/domain/runtime-state.ts: parseRuntimeState() is not yet a reliable fail-closed runtime schema boundary. It checks only a few top-level fields, then casts the input to RuntimeState. As a result, malformed persisted state can be accepted as valid, including:

    • unsupported/invalid local versions such as schemaVersion: 0, -1, or 1.5;
    • invalid enum values such as status: "done" or task/worker/evaluation statuses outside the declared unions;
    • malformed nested records in tasks, workers, evaluations, rewards, integrationCandidates, objective, and policySelection;
    • malformed nested artifact refs inside task/evaluation/reward/policy-selection structures.

    Since this PR’s contract is specifically “versioned schema + fail-closed parsing,” accepting malformed nested state defeats the main safety boundary. Please either add validation for the declared schema surfaces or explicitly narrow the parser’s documented responsibility and tests so it is not presented as validating RuntimeState.

Warnings / risks

  • src/domain/runtime-state.ts: validateArtifactRef() only checks that kind is a nonblank string, not that it is one of RuntimeArtifactKind. This can leak unknown artifact kinds through parseRuntimeState() and makes buildRunContractRuntimeRefs() dependent on partially trusted casted data.
  • test/runtime-state.test.ts: current tests cover happy-path representation and a few top-level failures, but do not assert rejection of invalid nested task/worker/evaluation/reward/integration shapes. That leaves the primary schema contract under-tested.

Suggestions

  • Add small enum guard helpers, e.g. isRuntimeStatus, isRuntimeTaskStatus, isRuntimeArtifactKind, and use them during parsing.
  • Consider validating schemaVersion === RUNTIME_STATE_SCHEMA_VERSION for now, unless older-version migrations are intentionally supported.
  • Add focused tests for:
    • invalid schemaVersion values below/current but malformed;
    • invalid top-level status;
    • non-array or malformed dependsOn, evidenceRefs, evaluationRefs;
    • malformed nested artifact refs;
    • invalid RuntimeArtifactKind.

Looks good

  • The change is appropriately bounded to the runtime-state schema slice, plus focused tests and README documentation.
  • The schema types are product-neutral and do not introduce GitHub/Ragna/kapi-agent semantics into the domain layer.
  • Unknown newer schema versions are rejected, which is the right compatibility posture.
  • buildRunContractRuntimeRefs() cleanly exposes only objective, policy-selection, and evaluation artifact refs.

Verification notes

  • Verifier gate status: PASS — npm ci && npm run verify exited 0.
  • Size gate status: PASS — 190 changed lines, under the 200-line semantic threshold.
  • Revision-explanation status: not required for this review; explanation found.
  • Ilchul review harness gate: PASS — STANDARD risk, neutral conclusion, no blocking findings.
  • Local inspection reviewed src/domain/runtime-state.ts, test/runtime-state.test.ts, and usage of parseRuntimeState(). The blocking issue is semantic contract coverage, not CI failure.

Engine: pi

@devkade devkade force-pushed the feat/issue-185-runstate-schema branch from d9d9f5b to 5785391 Compare May 17, 2026 19:06
@devkade
Copy link
Copy Markdown
Owner Author

devkade commented May 17, 2026

@kapi-agent review

Revision explanation for current head 5785391c6cd1df6f73e1f4b5d8a45bc73b639810:

What changed:

  • Hardened parseRuntimeState() to validate schemaVersion as a positive integer and reject unsupported newer versions.
  • Added enum validation for runtime status, task status, worker status, artifact kind, evaluation verdict, and integration candidate status.
  • Added nested validation for objective, policySelection, tasks, workers, evaluations, rewards, integrationCandidates, and nested artifact refs.
  • Extended tests for invalid local schema versions, invalid top-level status, invalid nested task/worker status, and invalid nested artifact kind.

Why this closes the prior feedback:

  • The parser no longer only casts top-level shape; it now fail-closes on the declared schema surfaces called out by the review.
  • Artifact refs now validate kind against RuntimeArtifactKind, so unknown kinds cannot pass through parsed state.

Verification:

  • npx tsx --test test/runtime-state.test.ts — pass
  • npm run check — pass
  • npm run check:unused — pass
  • npm run quality:budgets — pass with existing non-failing code_smells warning
  • npm run verify — pass, 509 passed / 11 skipped
  • git diff --check — pass

@kapi-agent
Copy link
Copy Markdown

kapi-agent Bot commented May 17, 2026

kapi-agent review completed

The formal GitHub PR review and required check were submitted separately. This request comment is kept concise to avoid duplicating the full review body.

kapi-agent request lifecycle:

  • Status: COMPLETED
  • Head: 5785391c6cd1
  • Formal review event: REQUEST_CHANGES
  • Review API status: 200
  • Required check API status: 201

Copy link
Copy Markdown

@kapi-agent kapi-agent Bot left a comment

Choose a reason for hiding this comment

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

kapi-agent review

Verdict: REQUEST_CHANGES

Blocking issues

  • src/domain/runtime-state.ts: createRuntimeState() does not actually reject a blank runId. It calls needText(input.runId, "runId", []), but the collected issue is discarded, so createRuntimeState({ runId: "", now }) returns an invalid RuntimeState. Since this PR establishes the executable schema boundary, the constructor should not create state that the parser would later reject. Please make this throw or otherwise fail closed, and add a focused test.

  • src/domain/runtime-state.ts: parseRuntimeState() still does not validate declared optional fields when present:

    • RuntimeWorkerSchema.readinessNonce?: string
    • EvaluationResultSchema.taskId?: string

    A persisted state with workers: [{ ..., readinessNonce: 123 }] or evaluations: [{ ..., taskId: {} }] is accepted and cast to RuntimeState. This keeps a gap in the “fail-closed parsing for declared schema surfaces” contract from the prior review. Please validate optional fields when present and cover them with tests.

Warnings / risks

  • src/domain/runtime-state.ts: timestamp validation uses Date.parse(), which accepts some non-ISO/date-like strings. If the intended persisted contract is ISO timestamps, this should be tightened now or documented as intentionally accepting any JavaScript-parseable timestamp.

Suggestions

  • Consider replacing needText(..., []) style validation in constructors with a helper that throws directly, so future constructor validation cannot silently discard issues.

Looks good

  • The revised parser now validates schema version shape, rejects newer schema versions, validates top-level runtime status, validates nested task/worker/evaluation/integration enum fields, and validates nested artifact refs.
  • The scope remains bounded to the runtime-state schema/versioning slice and does not mix in event replay or worker execution behavior.
  • README documentation was updated to mention the separate runtime state version boundary and RunContract-facing artifact refs.

Verification notes

  • Verifier gate status: PASS — npm ci && npm run verify exited 0.
  • Size gate status: PASS — 172 changed lines, below the 200-line semantic review threshold.
  • Revision-explanation status: PASS — current-head revision explanation was provided.
  • Ilchul review harness gate: PASS — STANDARD risk profile, no blocking findings.
  • Local/deeper inspection found the remaining schema-boundary issues above despite the automated gates passing.

Engine: pi

@devkade devkade force-pushed the feat/issue-185-runstate-schema branch from 5785391 to 70f0316 Compare May 17, 2026 19:09
@devkade
Copy link
Copy Markdown
Owner Author

devkade commented May 17, 2026

@kapi-agent review

Revision explanation for current head 70f0316b3349811de9a9f41cb23a696b4c34bc11:

What changed:

  • Fixed createRuntimeState() so blank runId throws instead of discarding validation issues.
  • Added optional-field validation for RuntimeWorkerSchema.readinessNonce and EvaluationResultSchema.taskId when present.
  • Extended regression coverage for blank constructor runId, malformed optional readiness nonce, and malformed optional evaluation task id.

Why this closes the prior feedback:

  • The constructor can no longer create state that the parser rejects for blank run ids.
  • Optional declared schema fields are now validated when present, closing the remaining parser cast gap.

Verification:

  • npx tsx --test test/runtime-state.test.ts — pass
  • npm run check — pass
  • npm run check:unused — pass
  • npm run quality:budgets — pass with existing non-failing code_smells warning
  • npm run verify — pass, 509 passed / 11 skipped
  • git diff --check — pass

@kapi-agent
Copy link
Copy Markdown

kapi-agent Bot commented May 17, 2026

kapi-agent review completed

The formal GitHub PR review and required check were submitted separately. This request comment is kept concise to avoid duplicating the full review body.

kapi-agent request lifecycle:

  • Status: COMPLETED
  • Head: 70f0316b3349
  • Formal review event: APPROVE
  • Review API status: 200
  • Required check API status: 201

Copy link
Copy Markdown

@kapi-agent kapi-agent Bot left a comment

Choose a reason for hiding this comment

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

kapi-agent review

Verdict: APPROVE

Final approval summary

Review journey

This PR defines the versioned RuntimeState schema boundary for the objective-driven runtime. The semantic scope is bounded to schema/types, fail-closed parsing, RunContract-facing runtime artifact refs, focused tests, and README documentation. It intentionally does not implement event replay, worker execution, storage migration, or runtime mutation.

There were two prior kapi-agent change requests:

  • First: parseRuntimeState() validated too little and cast malformed nested data as RuntimeState.
  • Second: createRuntimeState() allowed blank runId, and optional declared fields were not validated when present.

The current revision includes an author explanation and addresses those prior findings.

What changed

Important paths:

  • src/domain/runtime-state.ts
    • Adds RuntimeState.schemaVersion: 1.
    • Defines runtime objective, policy, task, worker, artifact ref, evaluation, reward, and integration candidate schema types.
    • Adds createRuntimeState(), parseRuntimeState(), and buildRunContractRuntimeRefs().
    • Validates top-level fields, enum values, nested arrays/records, nested artifact refs, optional fields, and newer unsupported schema versions.
  • test/runtime-state.test.ts
    • Adds initialization, fail-closed parsing, malformed nested field, blank constructor runId, optional-field, RunContract-ref, success, and repair-required examples.
  • README.md
    • Documents the separately versioned runtime state boundary and RunContract artifact-ref exposure.

Why this is correct

The previous blocking gaps are closed:

  • createRuntimeState() now calls requireText(input.runId, "runId"), so it cannot construct a blank-run-id state that the parser would later reject.
  • parseRuntimeState() now validates declared nested schema surfaces rather than accepting a shallow object and casting.
  • Optional fields called out in the prior review are validated when present:
    • RuntimeWorkerSchema.readinessNonce
    • EvaluationResultSchema.taskId
  • Unknown newer schema versions fail closed with unsupported-newer-schema, matching the stated compatibility contract.

Evidence

  • Verifier gate: PASS.
  • Size gate: PASS, 178 changed lines under the 200-line semantic threshold.
  • Ilchul review harness gate: PASS, STANDARD risk profile, no blocking findings.
  • Revision explanation status: required and found.
  • Automated verification evidence:
    • npm ci && npm run verify exited 0.
    • Full verifier included tests, type checks, unused checks, and quality budgets.
  • Inspected files:
    • src/domain/runtime-state.ts
    • test/runtime-state.test.ts
    • README.md

Remaining risks and approval rationale

Remaining risks are non-blocking:

  • Timestamp validation uses Date.parse(), which is permissive; acceptable for this slice unless strict RFC3339/ISO timestamp semantics become part of the persisted-state contract.
  • Extra unknown object fields are currently tolerated. That is compatible with an additive schema posture, but future storage/migration work should document whether unknown fields are preserved, ignored, or rejected.

Approval is justified because all configured gates pass, prior blocking feedback is addressed, tests cover the corrected behavior, and the implementation matches the narrow versioned-schema contract described by the PR.

Blocking issues

  • None.

Warnings / risks

  • src/domain/runtime-state.ts: Date.parse() accepts some loose date strings. If runtime state needs strict interoperable persistence, consider replacing it with a stricter timestamp validator in a follow-up.
  • src/domain/runtime-state.ts: unknown extra fields are accepted after validation. This is reasonable for additive compatibility, but should remain an explicit policy as migrations/event replay are added.

Suggestions

  • Consider adding table-driven negative tests later for each schema subsection as the runtime state grows.
  • Consider extracting validators into a small reusable schema-validation helper if more domain schemas adopt this pattern.

Looks good

  • The parser now fails closed on invalid schema versions, invalid enum values, malformed required fields, malformed nested arrays, malformed artifact refs, and the optional fields raised in the previous review.
  • buildRunContractRuntimeRefs() keeps the RunContract-facing artifact surface narrow.
  • The README update matches the implemented behavior without overclaiming event replay or execution semantics.

Verification notes

  • Verifier gate status: PASS — npm ci && npm run verify exited 0.
  • Size gate status: PASS — 178 changed lines, below threshold.
  • Revision-explanation status: required and found.
  • Ilchul review harness: PASS — STANDARD risk profile, no blocking findings.
  • Local inspection confirmed the current head contains the fixes described in the author’s revision explanation.

Engine: pi

@devkade
Copy link
Copy Markdown
Owner Author

devkade commented May 18, 2026

@kapi-agent review --force

Revision explanation for current head 32686594f675996dfc215ee1775e3d5611e9b754:

What changed

Why this closes the prior feedback

  • Preserves the previously approved runtime state implementation while satisfying the branch-up-to-date merge gate.

Verification

  • npm run check — pass
  • npm run verify — pass
  • git diff --check — pass

@devkade devkade force-pushed the feat/issue-185-runstate-schema branch from 70f0316 to 3268659 Compare May 18, 2026 03:56
@kapi-agent
Copy link
Copy Markdown

kapi-agent Bot commented May 18, 2026

kapi-agent review completed

The formal GitHub PR review and required check were submitted separately. This request comment is kept concise to avoid duplicating the full review body.

kapi-agent request lifecycle:

  • Status: COMPLETED
  • Head: 32686594f675
  • Formal review event: APPROVE
  • Review API status: 200
  • Required check API status: 201

Copy link
Copy Markdown

@kapi-agent kapi-agent Bot left a comment

Choose a reason for hiding this comment

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

kapi-agent review

Verdict: APPROVE

Final approval summary

Review journey

This PR adds a versioned RuntimeState schema boundary for the objective-driven runtime. The semantic scope is bounded to schema/types, fail-closed parsing, RunContract-facing runtime artifact references, focused tests, and README documentation.

Prior kapi-agent feedback requested stronger fail-closed validation for nested state, invalid enum/schema versions, constructor-created invalid runIds, and optional declared fields. Those issues were addressed in earlier revisions and approved. The current revision rebases the already-approved implementation onto current dev and preserves the README adjacency after related PRs landed.

What changed

Important paths:

  • src/domain/runtime-state.ts
    • Defines RuntimeState.schemaVersion: 1.
    • Adds runtime objective, policy, task, worker, artifact ref, evaluation, reward, and integration candidate schema types.
    • Adds createRuntimeState(), parseRuntimeState(), and buildRunContractRuntimeRefs().
    • Validates top-level and nested records, enum values, timestamps, required strings, optional declared fields, arrays, and artifact refs.
  • test/runtime-state.test.ts
    • Covers initialization, unsupported newer schemas, malformed timestamps/refs, invalid enums, malformed optional fields, blank constructor runId, RunContract-visible refs, and representative success/repair states.
  • README.md
    • Documents the separately versioned runtime state boundary and fail-closed newer-version behavior.

Why this is correct

The parser now acts as a real schema boundary rather than a shallow cast: malformed declared schema surfaces fail closed, unknown newer schema versions are not interpreted optimistically, and the constructor no longer creates state that the parser would reject. The RunContract helper exposes only the documented objective, policy-selection, and evaluation artifact refs.

The latest rebase does not appear to alter the approved runtime-state behavior; it only resolves branch freshness and README adjacency.

Evidence

  • Verifier gate: PASS — npm ci && npm run verify exited 0.
  • Size gate: PASS — 178 changed lines, below the configured 200-line review threshold.
  • Ilchul review harness gate: PASS — STANDARD risk, no blocking findings.
  • Revision explanation: present for the current head 32686594f675996dfc215ee1775e3d5611e9b754.
  • Inspected files: src/domain/runtime-state.ts, test/runtime-state.test.ts, README.md.
  • PR evidence also reports npm run check, npm run verify, and git diff --check passing after the rebase.

Remaining risks and approval rationale

Remaining risks are follow-up scope rather than blockers: event replay, worker execution, storage migration, and runtime mutation are intentionally not implemented in this slice. Approval is justified because the PR’s bounded schema/versioning contract is implemented, tested, documented, and the prior kapi-agent blocking issues are closed.

Blocking issues

None.

Warnings / risks

  • src/domain/runtime-state.ts: timestamp validation still uses Date.parse(), which is permissive. This is acceptable for the current schema boundary, but stricter ISO timestamp validation may be worth adding before persisted runtime state becomes externally produced or migration-sensitive.
  • Runtime behavior beyond schema validation remains follow-up work: event replay, worker lifecycle mutation, storage migration, and live execution are not covered by this PR.

Suggestions

  • Consider adding a small future test for rejecting non-ISO-but-parseable timestamps if the project wants a stricter timestamp contract.
  • As the schema grows, consider splitting validators into smaller schema modules or table-driven validators to keep runtime-state.ts maintainable.

Looks good

  • The parser now validates nested declared surfaces instead of relying on unsafe casts.
  • Unsupported newer schema versions fail closed with a distinct reason.
  • createRuntimeState() enforces required runId and timestamp inputs.
  • RunContract-facing refs are intentionally narrowed to objective, policy-selection, and evaluation artifacts.
  • Tests directly cover the previously requested regression cases.

Verification notes

  • Verifier gate status: PASS — npm ci && npm run verify exited 0.
  • Size gate status: PASS — 178 changed lines < 200.
  • Revision-explanation status: PASS — current-head explanation was provided.
  • Ilchul review harness: PASS — STANDARD risk, no blocking findings.
  • Local/CI evidence supplied: npm run check, npm run verify, and git diff --check pass.

Engine: pi

@devkade devkade merged commit 1cbdbb5 into dev May 18, 2026
2 checks passed
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.

Design: define RunState schemas, versions, and migration policy

1 participant