aiki-cli 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -5
- package/README.md +73 -15
- package/dist/bench/idea-v3-bench.js +104 -5
- package/dist/bench/idea-v3-rating.js +159 -4
- package/dist/cli/bench.js +5 -5
- package/dist/cli/index.js +12 -2
- package/dist/cli/resume.js +20 -0
- package/dist/cli/run.js +76 -5
- package/dist/cli/serve.js +48 -0
- package/dist/config/config.js +7 -2
- package/dist/council/view.js +64 -15
- package/dist/orchestration/auto-profile.js +97 -0
- package/dist/orchestration/claim-groups.js +56 -0
- package/dist/orchestration/context.js +69 -6
- package/dist/orchestration/decision-dossier.js +450 -89
- package/dist/orchestration/decision-graph.js +33 -2
- package/dist/orchestration/engine.js +8 -4
- package/dist/orchestration/evidence-origin.js +17 -0
- package/dist/orchestration/jsonStage.js +47 -5
- package/dist/orchestration/legacy-idea-adapter.js +3 -0
- package/dist/orchestration/modes.js +18 -10
- package/dist/orchestration/preflight.js +36 -3
- package/dist/orchestration/quick-analysis.js +29 -7
- package/dist/orchestration/sanitize-paths.js +10 -0
- package/dist/orchestration/stages/s10-render.js +196 -84
- package/dist/orchestration/stages/s4-analyze.js +10 -2
- package/dist/orchestration/stages/s4b-challenge.js +97 -0
- package/dist/orchestration/stages/s5-drift.js +13 -3
- package/dist/orchestration/stages/s6-positions.js +18 -0
- package/dist/orchestration/stages/s7-decision-graph.js +3 -0
- package/dist/orchestration/stages/s8-verify.js +66 -12
- package/dist/orchestration/stages/s8b-rebuttal.js +11 -4
- package/dist/orchestration/stages/s9-judge.js +52 -14
- package/dist/orchestration/stages/s9b-plan.js +227 -48
- package/dist/orchestration/url-sources.js +21 -0
- package/dist/providers/adapter-core.js +1 -1
- package/dist/providers/claude.js +18 -0
- package/dist/schemas/index.js +112 -3
- package/dist/serve/flight-deck.js +830 -0
- package/dist/serve/followup.js +50 -0
- package/dist/serve/frames.js +168 -0
- package/dist/serve/gates.js +72 -0
- package/dist/serve/projections.js +283 -0
- package/dist/serve/server.js +219 -0
- package/dist/serve/threads.js +145 -0
- package/dist/serve-ui/Five.png +0 -0
- package/dist/serve-ui/app.js +820 -0
- package/dist/serve-ui/index.html +171 -0
- package/dist/serve-ui/workspace.css +662 -0
- package/dist/skills/idea-refinement/analyst.md +5 -5
- package/dist/skills/idea-refinement/chair.md +18 -0
- package/dist/skills/idea-refinement/economics-delivery.md +11 -0
- package/dist/skills/idea-refinement/market-adoption.md +12 -0
- package/dist/skills/idea-refinement/planner.md +25 -19
- package/dist/skills/idea-refinement/rebuttal.md +15 -0
- package/dist/skills/idea-refinement/verifier.md +17 -0
- package/dist/storage/runs.js +2 -1
- package/dist/workflows/idea-refinement.js +130 -24
- package/package.json +2 -2
package/dist/schemas/index.js
CHANGED
|
@@ -186,6 +186,7 @@ export const PreflightReading = z.object({
|
|
|
186
186
|
missing_evidence: z.array(z.string().min(1)).max(8),
|
|
187
187
|
domain_dimensions: z.array(DomainDimension).min(3).max(5),
|
|
188
188
|
questions: z.array(RunBriefQuestion).max(4),
|
|
189
|
+
requested_outputs: z.array(RequestedOutputSchema).max(4).default([]),
|
|
189
190
|
}).strict().superRefine((reading, ctx) => {
|
|
190
191
|
checkQuestionIds(reading.questions, ctx);
|
|
191
192
|
checkDomainDimensionIds(reading.domain_dimensions, ctx);
|
|
@@ -236,6 +237,7 @@ export const ClaimPosition = z
|
|
|
236
237
|
dimension_id: z.string().min(1),
|
|
237
238
|
stance: z.enum(['SUPPORT', 'OPPOSE', 'MIXED', 'UNKNOWN']),
|
|
238
239
|
basis: z.enum(['EVIDENCE', 'INFERENCE', 'ASSUMPTION']),
|
|
240
|
+
nature: z.enum(['FACTUAL', 'JUDGMENT']).default('JUDGMENT'),
|
|
239
241
|
load_bearing: z.boolean(),
|
|
240
242
|
if_false: z.enum(['STOP', 'PIVOT', 'CONDITION', 'MINOR']),
|
|
241
243
|
reasoning: z.string().min(1),
|
|
@@ -316,6 +318,14 @@ export const DecisionQuestion = z
|
|
|
316
318
|
claim_ids: z.array(z.string().min(1)),
|
|
317
319
|
})
|
|
318
320
|
.strict();
|
|
321
|
+
export const DeliverableProposal = z.object({
|
|
322
|
+
output: z.enum(['FEATURE_BACKLOG', 'IMPLEMENTATION_PLAN']),
|
|
323
|
+
title: z.string().min(1),
|
|
324
|
+
detail: z.string().min(1),
|
|
325
|
+
user_value: z.string().min(1),
|
|
326
|
+
why_distinctive: z.string().min(1),
|
|
327
|
+
evidence_ids: z.array(z.string().min(1)).max(6),
|
|
328
|
+
}).strict();
|
|
319
329
|
const IdeaRoleOutputBase = z
|
|
320
330
|
.object({
|
|
321
331
|
workflow: z.literal('idea-refinement'),
|
|
@@ -326,6 +336,7 @@ const IdeaRoleOutputBase = z
|
|
|
326
336
|
calculations: z.array(CalculationLedger).max(8).default([]),
|
|
327
337
|
coverage: z.array(CoverageEntry).max(18), // 13 core + up to 5 preflight domain dimensions
|
|
328
338
|
decision_questions: z.array(DecisionQuestion).max(8),
|
|
339
|
+
deliverable_proposals: z.array(DeliverableProposal).max(8).default([]),
|
|
329
340
|
})
|
|
330
341
|
.strict();
|
|
331
342
|
function checkSubmissionRefs(submission, ctx) {
|
|
@@ -395,6 +406,12 @@ function checkSubmissionRefs(submission, ctx) {
|
|
|
395
406
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['decision_questions', index, 'claim_ids'], message: `unknown position id: ${id}` });
|
|
396
407
|
}
|
|
397
408
|
}
|
|
409
|
+
for (const [index, proposal] of submission.deliverable_proposals.entries()) {
|
|
410
|
+
for (const id of proposal.evidence_ids) {
|
|
411
|
+
if (!evidenceIds.has(id))
|
|
412
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['deliverable_proposals', index, 'evidence_ids'], message: `unknown evidence id: ${id}` });
|
|
413
|
+
}
|
|
414
|
+
}
|
|
398
415
|
}
|
|
399
416
|
export const IdeaRoleOutput = IdeaRoleOutputBase.superRefine(checkSubmissionRefs);
|
|
400
417
|
/** Defect categories a finding (and a seeded bug, T11) can carry. BENCHMARK.md's "defect class" match
|
|
@@ -527,6 +544,17 @@ export function salvageIdeaRoleOutputModel(input) {
|
|
|
527
544
|
&& calc.inputs.every((input) => input.evidence_ids.every((id) => keptEvidence.has(id))))
|
|
528
545
|
.slice(0, 8)
|
|
529
546
|
: output.calculations;
|
|
547
|
+
const deliverableProposals = parseOrDrop(output.deliverable_proposals, (item) => {
|
|
548
|
+
if (!item || typeof item !== 'object' || Array.isArray(item))
|
|
549
|
+
return DeliverableProposal.safeParse(item);
|
|
550
|
+
const proposal = item;
|
|
551
|
+
return DeliverableProposal.strip().safeParse({
|
|
552
|
+
...proposal,
|
|
553
|
+
evidence_ids: Array.isArray(proposal.evidence_ids)
|
|
554
|
+
? proposal.evidence_ids.filter((id) => keptEvidence.has(id))
|
|
555
|
+
: proposal.evidence_ids,
|
|
556
|
+
});
|
|
557
|
+
});
|
|
530
558
|
return {
|
|
531
559
|
...output,
|
|
532
560
|
evidence,
|
|
@@ -534,6 +562,7 @@ export function salvageIdeaRoleOutputModel(input) {
|
|
|
534
562
|
calculations,
|
|
535
563
|
coverage: parseOrDrop(scrubIds(output.coverage, 'position_ids'), (item) => CoverageEntryBase.strip().superRefine(checkCoverageEntry).safeParse(item)),
|
|
536
564
|
decision_questions: parseOrDrop(scrubIds(output.decision_questions, 'claim_ids'), (item) => DecisionQuestion.strip().safeParse(item)),
|
|
565
|
+
deliverable_proposals: deliverableProposals,
|
|
537
566
|
};
|
|
538
567
|
}
|
|
539
568
|
/** The model-facing S4 shape. Exact known enum aliases are canonicalized, then the strict schema validates
|
|
@@ -588,6 +617,7 @@ export const DecisionClaim = z.object({
|
|
|
588
617
|
position_ids: z.array(z.string().min(1)).min(1),
|
|
589
618
|
state: z.enum(['CONSENSUS', 'SHARED_CONCERN', 'DISAGREEMENT', 'UNIQUE', 'UNCERTAIN']),
|
|
590
619
|
evidence_state: z.enum(['SUPPORTED', 'CONFLICTED', 'UNVERIFIED']),
|
|
620
|
+
nature: z.enum(['FACTUAL', 'JUDGMENT']).default('JUDGMENT'),
|
|
591
621
|
load_bearing: z.boolean(),
|
|
592
622
|
if_false: z.enum(['STOP', 'PIVOT', 'CONDITION', 'MINOR']),
|
|
593
623
|
sensitivity: z.enum(['DECISIVE', 'MATERIAL', 'LOW']),
|
|
@@ -635,8 +665,27 @@ export const ClaimVerification = z.object({
|
|
|
635
665
|
calculation_check: z.enum(['PASS', 'FAIL', 'NOT_APPLICABLE']).optional(),
|
|
636
666
|
missing_evidence: z.array(z.string().min(1)),
|
|
637
667
|
}).strict();
|
|
668
|
+
/** v6 semantic claim join: S8 may group claims that assert the same proposition in different
|
|
669
|
+
* words (SAME) or directly contradict each other (OPPOSES). `.catch(undefined)` keeps a
|
|
670
|
+
* malformed grouping from ever costing the verification set — groups are a bonus, never a risk. */
|
|
671
|
+
export const ClaimGroup = z.object({
|
|
672
|
+
ids: z.array(z.string().min(1)).min(2).max(8),
|
|
673
|
+
relation: z.enum(['SAME', 'OPPOSES']),
|
|
674
|
+
}).strict();
|
|
638
675
|
export const ClaimVerificationSet = z.object({
|
|
639
676
|
verifications: z.array(ClaimVerification),
|
|
677
|
+
claim_groups: z.array(ClaimGroup).max(12).optional().catch(undefined),
|
|
678
|
+
}).strict();
|
|
679
|
+
// ── v7 Phase D: targeted auto-mode challenge delta ─────────────────────────
|
|
680
|
+
export const ChallengeDelta = z.object({
|
|
681
|
+
claimId: z.string().min(1),
|
|
682
|
+
response: z.enum(['CONFIRM', 'COUNTER', 'NARROW', 'REPLACE', 'UNRESOLVED']),
|
|
683
|
+
reasoning: z.string().min(1),
|
|
684
|
+
newEvidenceIds: z.array(z.string().min(1)),
|
|
685
|
+
changedDecisionImpact: z.string().min(1),
|
|
686
|
+
}).strict();
|
|
687
|
+
export const ChallengeDeltaSet = z.object({
|
|
688
|
+
deltas: z.array(ChallengeDelta).max(3),
|
|
640
689
|
}).strict();
|
|
641
690
|
// ── R5: bounded, append-only rebuttal events ───────────────────────────────
|
|
642
691
|
const RebuttalResponseBase = z.object({
|
|
@@ -899,7 +948,32 @@ export const ImplementationPlan = z.object({
|
|
|
899
948
|
acceptance_test: z.string().min(1),
|
|
900
949
|
}).strict()).min(1).max(7),
|
|
901
950
|
}).strict();
|
|
902
|
-
|
|
951
|
+
const ReaderBriefBase = z.object({
|
|
952
|
+
headline: z.string().min(1).max(160),
|
|
953
|
+
bottom_line: z.string().min(1).max(1200),
|
|
954
|
+
sections: z.array(z.object({
|
|
955
|
+
heading: z.string().min(1).max(120),
|
|
956
|
+
summary: z.string().min(1).max(1000),
|
|
957
|
+
bullets: z.array(z.string().min(1).max(500)).max(6),
|
|
958
|
+
}).strict()).min(2).max(6),
|
|
959
|
+
next_step: z.string().min(1).max(600),
|
|
960
|
+
caveats: z.array(z.string().min(1).max(500)).max(3),
|
|
961
|
+
source_ids: z.array(z.string().min(1)).max(8),
|
|
962
|
+
}).strict();
|
|
963
|
+
const READER_AUDIT_ENUM = /\b(?:UNVERIFIED|UNVERIFIABLE|PARTIAL|CONFLICTED)\b/;
|
|
964
|
+
const READER_AUDIT_LANGUAGE = /\b(?:structural score|evidence coverage|verification coverage|claim ids?|graph ids?|provider calls?|model calls?|answer editor|reader_brief)\b/i;
|
|
965
|
+
export const ReaderBrief = ReaderBriefBase.superRefine((brief, ctx) => {
|
|
966
|
+
const text = JSON.stringify(brief);
|
|
967
|
+
if (READER_AUDIT_ENUM.test(text) || READER_AUDIT_LANGUAGE.test(text)) {
|
|
968
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'reader_brief contains internal audit language' });
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
/** Contextual reader-language check: only reject IDs that actually exist in this run. */
|
|
972
|
+
export function readerBriefIssues(brief, knownIds) {
|
|
973
|
+
const text = JSON.stringify(brief);
|
|
974
|
+
return [...knownIds].filter((id) => new RegExp(`\\b${id.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`).test(text));
|
|
975
|
+
}
|
|
976
|
+
const ActionPlanBase = z
|
|
903
977
|
.object({
|
|
904
978
|
actions: z
|
|
905
979
|
.array(z
|
|
@@ -912,13 +986,19 @@ export const ActionPlan = z
|
|
|
912
986
|
kill_signal: z.string().min(1),
|
|
913
987
|
})
|
|
914
988
|
.strict())
|
|
915
|
-
.min(1)
|
|
916
989
|
.max(7),
|
|
917
990
|
sequencing_note: z.string().min(1),
|
|
918
991
|
feature_backlog: FeatureBacklog.optional(),
|
|
919
992
|
implementation_plan: ImplementationPlan.optional(),
|
|
993
|
+
// Optional only so pre-v5 run artifacts remain replayable. New decision contracts require it in S9b.
|
|
994
|
+
reader_brief: ReaderBrief.optional(),
|
|
920
995
|
})
|
|
921
996
|
.strict();
|
|
997
|
+
export const ActionPlan = ActionPlanBase.superRefine((plan, ctx) => {
|
|
998
|
+
if (plan.actions.length === 0 && !plan.reader_brief) {
|
|
999
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['actions'], message: 'an empty action plan requires reader_brief' });
|
|
1000
|
+
}
|
|
1001
|
+
});
|
|
922
1002
|
export const PlannerUnavailable = z.object({
|
|
923
1003
|
kind: z.literal('PlannerUnavailable'),
|
|
924
1004
|
reason: z.enum(['budget_exhausted', 'planner_failed']),
|
|
@@ -934,7 +1014,7 @@ export const QuickDecisionModel = z.object({
|
|
|
934
1014
|
key_points: z.array(z.string().min(1)).min(2).max(8),
|
|
935
1015
|
dissent: z.array(z.string().min(1)).min(1).max(4),
|
|
936
1016
|
confidence_notes: z.string().min(1),
|
|
937
|
-
action_plan:
|
|
1017
|
+
action_plan: ActionPlanBase.extend({ reader_brief: ReaderBrief }),
|
|
938
1018
|
}).strict().superRefine((decision, ctx) => {
|
|
939
1019
|
const hasConditions = decision.conditions.length > 0;
|
|
940
1020
|
if (decision.recommendation === 'PROCEED_WITH_CONDITIONS' && !hasConditions) {
|
|
@@ -947,6 +1027,16 @@ export const QuickDecisionModel = z.object({
|
|
|
947
1027
|
// ── RunMeta (§15, §16) ──────────────────────────────────────────────────────
|
|
948
1028
|
//
|
|
949
1029
|
// Written by the artifact writer; assembled by the engine's RunCtx (T5). Internal → not strict.
|
|
1030
|
+
/** Per-call token accounting. `estimated:true` = local chars/4 estimate, never blended
|
|
1031
|
+
* silently with provider-reported numbers. */
|
|
1032
|
+
export const NormalizedUsageSchema = z.object({
|
|
1033
|
+
inputTokens: z.number().int().nonnegative().optional(),
|
|
1034
|
+
outputTokens: z.number().int().nonnegative().optional(),
|
|
1035
|
+
cacheReadTokens: z.number().int().nonnegative().optional(),
|
|
1036
|
+
cacheWriteTokens: z.number().int().nonnegative().optional(),
|
|
1037
|
+
estimated: z.boolean(),
|
|
1038
|
+
reportedCostUsd: z.number().nonnegative().optional(),
|
|
1039
|
+
});
|
|
950
1040
|
/** One provider call's accounting entry (§15 "per-call timings"). */
|
|
951
1041
|
export const CallRecord = z.object({
|
|
952
1042
|
provider: ProviderIdSchema,
|
|
@@ -954,6 +1044,7 @@ export const CallRecord = z.object({
|
|
|
954
1044
|
category: z.enum(['discovery', 'verification', 'repair', 'planning']).optional(),
|
|
955
1045
|
durationMs: z.number().nonnegative(),
|
|
956
1046
|
error: z.enum(['NOT_FOUND', 'AUTH', 'QUOTA', 'TIMEOUT', 'BAD_OUTPUT', 'CRASH']).optional(),
|
|
1047
|
+
usage: NormalizedUsageSchema.optional(),
|
|
957
1048
|
});
|
|
958
1049
|
/** How read-only was actually enforced per provider (§15, §19). Mirrors providers ReadOnlyFlag. */
|
|
959
1050
|
const ReadOnlyFlagSchema = z.enum(['plan', 'sandbox', 'none']);
|
|
@@ -981,17 +1072,35 @@ export const RunMeta = z.object({
|
|
|
981
1072
|
repair: z.number().int().nonnegative(),
|
|
982
1073
|
planning: z.number().int().nonnegative(),
|
|
983
1074
|
}).optional(),
|
|
1075
|
+
usage_totals: z.object({
|
|
1076
|
+
inputTokens: z.number().int().nonnegative(),
|
|
1077
|
+
outputTokens: z.number().int().nonnegative(),
|
|
1078
|
+
reportedCalls: z.number().int().nonnegative(),
|
|
1079
|
+
estimatedCalls: z.number().int().nonnegative(),
|
|
1080
|
+
reportedCostUsd: z.number().nonnegative().optional(),
|
|
1081
|
+
}).optional(),
|
|
1082
|
+
// v7 Phase B: present only when the user ran `--mode auto`; records the resolved mode + why.
|
|
1083
|
+
auto_decision: z.object({
|
|
1084
|
+
resolved: z.enum(['quick', 'council']),
|
|
1085
|
+
reasons: z.array(z.string()),
|
|
1086
|
+
fast_path: z.boolean().optional(),
|
|
1087
|
+
escalation_reasons: z.array(z.string().min(1)).optional(),
|
|
1088
|
+
}).optional(),
|
|
984
1089
|
exit_status: z.enum(['ok', 'failed', 'aborted', 'partial']),
|
|
985
1090
|
aborted: z.boolean(), // §16: Ctrl+C finalizes meta with aborted:true
|
|
986
1091
|
// §16 report-header flags; absent = none.
|
|
987
1092
|
flags: z.array(z.enum([
|
|
988
1093
|
'synthesis_suspect',
|
|
989
1094
|
'low_diversity',
|
|
1095
|
+
'weak_seat',
|
|
990
1096
|
'plan_skipped',
|
|
991
1097
|
'plan_fallback',
|
|
1098
|
+
'plan_partial',
|
|
992
1099
|
'headless_intent',
|
|
993
1100
|
'verification_skipped',
|
|
994
1101
|
'research_ungrounded',
|
|
1102
|
+
'source_fallback_search',
|
|
1103
|
+
'deliverable_gap',
|
|
995
1104
|
'single_model',
|
|
996
1105
|
])).optional(),
|
|
997
1106
|
});
|