-
Notifications
You must be signed in to change notification settings - Fork 0
feat(core): Moirai F1 common contracts (judgment, context projection, persona schema, catalog/policy, store) #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
47 commits
Select commit
Hold shift + click to select a range
2dd3a74
feat(core): add judgment contract types, parsers and intention transi…
thisisjun786 4335e94
feat(core): export parseObjectiveProfileRef for judgment store re-par…
thisisjun786 17db2c1
feat(core): add PersonaSchema v1 contract and LifeDefinition derivati…
thisisjun786 53a0be1
feat(core): add ContextReadProjection separating working and instruct…
thisisjun786 4c17e1d
feat(core): add personal.v1 option catalog and arbitration policy rev…
thisisjun786 71dcf58
fix(core): preserve catalog rejection precedence and clear literal-ke…
thisisjun786 33d888b
style(core): reformat judgment-validation.ts after parseObjectiveProf…
thisisjun786 fdcb794
feat(core): add JudgmentStore standalone SQLite persistence for round…
thisisjun786 d6ddd33
refactor(core): share JSON canonicalizer between judgment digest and …
thisisjun786 8c4eb98
test(core): prove shared judgment canonicalizer through public barrel…
thisisjun786 02cb0ef
test(core): add end-to-end personal.v1 judgment round fixture (F1 int…
thisisjun786 7e9bffc
test(core): assert judgment round reload against original in-memory r…
thisisjun786 b028518
test(core): import behaviorFingerprint through the agents barrel in p…
thisisjun786 e597594
fix(core): harden judgment transitions, policy and store consistency
thisisjun786 8cf0198
test(core): prove judgment canonical JSON bounds through the agents b…
thisisjun786 c37851c
fix(core): preserve persona projection allowlists
thisisjun786 8cc88f6
fix(core): validate restored context projections
thisisjun786 4512d67
fix(core): bind judgment actions and frozen provenance
thisisjun786 67bf83b
test(runtime): finalize SQLite state at cold restart
thisisjun786 2dabeda
test(runtime): isolate the LIFE archive capacity boundary
thisisjun786 f8b48fa
fix(core): enforce the immutable personal policy declaration
thisisjun786 6ea9cec
fix(core): apply context ID bounds to instruction references
thisisjun786 6175e8a
fix(core): verify persisted judgment digests on retrieval
thisisjun786 f443122
fix(core): preserve LIFE persona ownership restrictions
thisisjun786 e5dcaaa
fix(core): bound canonical option keys for valid targets
thisisjun786 a8c9340
fix(core): honor judgment source ownership contracts
thisisjun786 d9cadf7
fix(core): bind candidates and concessions to the round
thisisjun786 1370e90
test(core): isolate stable orphan quota adoption setup
thisisjun786 7bff0ae
fix(core): validate identity policy before persona derivation
thisisjun786 3b769eb
fix(core): preserve abstention and neural failure semantics
thisisjun786 49b2dbb
fix(core): audit judgment ledger before scoped operations
thisisjun786 d17c33e
fix(core): validate previous context projections before reuse
thisisjun786 21cd1aa
fix(core): identify protected commitments in judgment evidence
thisisjun786 9c565b3
fix(core): ground commitment exemptions and judgment inputs
thisisjun786 66f9c84
fix(core): replay judgment policy from frozen candidate inputs
thisisjun786 dfadcea
test(runtime): finalize SQLite state before binding restart
thisisjun786 46b4b77
fix(core): require canonical intention timestamps
thisisjun786 7eac3fe
fix(core): verify arbitration evidence and currentness
thisisjun786 ebd7af9
fix(core): persist candidate-free dialogue judgments
thisisjun786 5484813
fix(core): validate source intentions before transitions
thisisjun786 fb15519
fix(core): close dialogue and snapshot boundary gaps
thisisjun786 ee47070
fix(core): enforce intention chronology and raw argument bounds
thisisjun786 be29476
test(runtime): isolate persona restart resources
thisisjun786 cf3a46e
fix(core): reject cross-module objective aliases
thisisjun786 fdce947
fix(core): fence unverified user commitment cancellation
thisisjun786 0785eda
fix(core): prevent objective reactivation from reviving stale rounds
thisisjun786 ff241e6
fix(core): bind dialogue digests to frozen source provenance
thisisjun786 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| import { INTENTION_STATUSES, type IntentionStatus } from "./judgment.ts"; | ||
| import { | ||
| type CanonicalOption, | ||
| parseCanonicalOption, | ||
| } from "./judgment-catalog.ts"; | ||
| import type { HostEligibility } from "./judgment-policy.ts"; | ||
| import { judgmentDigest } from "./judgment-validation.ts"; | ||
| import { boundedId, boundedText } from "./validation.ts"; | ||
|
|
||
| /** Closed Host inputs, independent of assessment arrival order and session lifetime. */ | ||
| export type CandidateSet = { | ||
| schemaVersion: 1; | ||
| roundId: string; | ||
| snapshotDigest: string; | ||
| options: CanonicalOption[]; | ||
| eligibility: HostEligibility; | ||
| intentionRefs: Array<{ | ||
| intentionId: string; | ||
| revision: number; | ||
| status: IntentionStatus; | ||
| digest: string; | ||
| }>; | ||
| candidateDigest: string; | ||
| }; | ||
|
|
||
| function fields( | ||
| value: unknown, | ||
| keys: string[], | ||
| label: string, | ||
| ): Record<string, unknown> { | ||
| if ( | ||
| value === null || | ||
| typeof value !== "object" || | ||
| Array.isArray(value) || | ||
| Object.getPrototypeOf(value) !== Object.prototype | ||
| ) | ||
| throw Error(`invalid ${label}`); | ||
| const row = value as Record<string, unknown>; | ||
| for (const key of Object.keys(row)) | ||
| if (!keys.includes(key)) throw Error(`unknown ${label} field ${key}`); | ||
| for (const key of keys) | ||
| if (!Object.hasOwn(row, key)) throw Error(`missing ${label} field ${key}`); | ||
| return row; | ||
| } | ||
| function list<T>(value: unknown, parse: (value: unknown) => T): T[] { | ||
| if (!Array.isArray(value) || value.length > 256) | ||
| throw Error("invalid candidate list"); | ||
| return Array.from(value, parse); | ||
| } | ||
| function unique<T>(items: T[], key: (item: T) => string): T[] { | ||
| if (new Set(items.map(key)).size !== items.length) | ||
| throw Error("duplicate candidate key"); | ||
| return items; | ||
| } | ||
| function sorted<T>(items: T[], key: (item: T) => string): T[] { | ||
| return unique(items, key).sort((a, b) => | ||
| key(a) < key(b) ? -1 : key(a) > key(b) ? 1 : 0, | ||
| ); | ||
| } | ||
|
|
||
| function candidateBody(value: unknown): Omit<CandidateSet, "candidateDigest"> { | ||
| const { | ||
| schemaVersion, | ||
| roundId, | ||
| snapshotDigest, | ||
| options: rawOptions, | ||
| eligibility: rawEligibility, | ||
| intentionRefs: rawRefs, | ||
| } = fields( | ||
| value, | ||
| [ | ||
| "schemaVersion", | ||
| "roundId", | ||
| "snapshotDigest", | ||
| "options", | ||
| "eligibility", | ||
| "intentionRefs", | ||
| ], | ||
| "candidate set", | ||
| ); | ||
| if (schemaVersion !== 1) | ||
| throw Error("Unsupported candidate set schema version"); | ||
| const options = sorted( | ||
| list(rawOptions, parseCanonicalOption), | ||
| (o) => o.optionKey, | ||
| ); | ||
| const actor = options[0]?.actor; | ||
| if ( | ||
| options.some( | ||
| (o) => | ||
| o.actor.agentId !== actor?.agentId || | ||
| o.actor.scopeId !== actor?.scopeId, | ||
| ) | ||
| ) | ||
| throw Error("candidate actor mismatch"); | ||
| const keys = new Set(options.map((o) => o.optionKey)); | ||
| // Eligibility is an ordered Host list, not a derived/defaulted set. Missing | ||
| // rows remain missing and the policy treats them as ineligible. | ||
| const eligibility = unique( | ||
| list(rawEligibility, (value) => { | ||
| const { | ||
| optionKey: rawKey, | ||
| eligible, | ||
| reason, | ||
| } = fields( | ||
| value, | ||
| ["optionKey", "eligible", "reason"], | ||
| "candidate eligibility", | ||
| ); | ||
| const optionKey = boundedId(rawKey, "option key"); | ||
| if (!keys.has(optionKey)) throw Error("unknown eligibility option key"); | ||
| if (typeof eligible !== "boolean") | ||
| throw Error("invalid candidate eligibility"); | ||
| return { | ||
| optionKey, | ||
| eligible, | ||
| reason: | ||
| reason === null ? null : boundedText(reason, "eligibility reason"), | ||
| }; | ||
| }), | ||
| (r) => r.optionKey, | ||
| ); | ||
| const intentionRefs = sorted( | ||
| list(rawRefs, (value) => { | ||
| const { | ||
| intentionId, | ||
| revision, | ||
| status: rawStatus, | ||
| digest, | ||
| } = fields( | ||
| value, | ||
| ["intentionId", "revision", "status", "digest"], | ||
| "candidate intention ref", | ||
| ); | ||
| const status = INTENTION_STATUSES.find((s) => s === rawStatus); | ||
| if ( | ||
| typeof revision !== "number" || | ||
| !Number.isSafeInteger(revision) || | ||
| revision < 0 || | ||
| status === undefined | ||
| ) | ||
| throw Error("invalid candidate intention ref"); | ||
| return { | ||
| intentionId: boundedId(intentionId, "intention id"), | ||
| revision, | ||
| status, | ||
| digest: boundedId(digest, "intention digest"), | ||
| }; | ||
| }), | ||
| (r) => r.intentionId, | ||
| ); | ||
| return { | ||
| schemaVersion: 1, | ||
| roundId: boundedId(roundId, "round id"), | ||
| snapshotDigest: boundedId(snapshotDigest, "snapshot digest"), | ||
| options, | ||
| eligibility, | ||
| intentionRefs, | ||
| }; | ||
| } | ||
|
|
||
| export function parseCandidateSet(value: unknown): CandidateSet { | ||
| const row = fields( | ||
| value, | ||
| [ | ||
| "schemaVersion", | ||
| "roundId", | ||
| "snapshotDigest", | ||
| "options", | ||
| "eligibility", | ||
| "intentionRefs", | ||
| "candidateDigest", | ||
| ], | ||
| "candidate set", | ||
| ); | ||
| const { candidateDigest, ...rest } = row; | ||
| const result = candidateBody(rest); | ||
| if (candidateDigest !== judgmentDigest(result)) | ||
| throw Error("candidate set digest mismatch"); | ||
| return { ...result, candidateDigest }; | ||
| } | ||
|
|
||
| export function buildCandidateSet(input: { | ||
| roundId: string; | ||
| snapshotDigest: string; | ||
| options: CanonicalOption[]; | ||
| eligibility: HostEligibility; | ||
| intentionRefs: CandidateSet["intentionRefs"]; | ||
| }): CandidateSet { | ||
| const result = candidateBody({ schemaVersion: 1, ...input }); | ||
| return { ...result, candidateDigest: judgmentDigest(result) }; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.