@gajae-code/coding-agent 0.11.8 → 0.11.9

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +18 -1
  2. package/dist/types/cli.d.ts +1 -0
  3. package/dist/types/config/model-profiles.d.ts +2 -3
  4. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +12 -5
  5. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +8 -0
  6. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +41 -0
  7. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +32 -17
  8. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +17 -0
  9. package/dist/types/gjc-runtime/deep-interview-state.d.ts +135 -4
  10. package/dist/types/gjc-runtime/state-writer.d.ts +44 -0
  11. package/dist/types/gjc-runtime/workflow-manifest.d.ts +5 -3
  12. package/dist/types/modes/components/welcome.d.ts +2 -0
  13. package/dist/types/runtime-mcp/redaction.d.ts +2 -0
  14. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -1
  15. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +3 -1
  16. package/dist/types/session/internal/managed-session-scope.d.ts +12 -2
  17. package/dist/types/session/internal/managed-session-storage.d.ts +8 -3
  18. package/dist/types/session/session-manager.d.ts +5 -1
  19. package/dist/types/session/session-storage.d.ts +13 -0
  20. package/dist/types/skill-state/active-state.d.ts +4 -0
  21. package/package.json +8 -8
  22. package/src/cli/mcp-cli.ts +4 -21
  23. package/src/cli.ts +32 -0
  24. package/src/commands/deep-interview.ts +9 -4
  25. package/src/commit/agentic/index.ts +3 -3
  26. package/src/commit/map-reduce/index.ts +2 -2
  27. package/src/config/model-profiles.ts +2 -3
  28. package/src/defaults/gjc/skills/deep-interview/SKILL.md +78 -163
  29. package/src/gjc-runtime/deep-interview-ambiguity.ts +68 -47
  30. package/src/gjc-runtime/deep-interview-draft.ts +842 -0
  31. package/src/gjc-runtime/deep-interview-payload.ts +262 -0
  32. package/src/gjc-runtime/deep-interview-recorder.ts +294 -226
  33. package/src/gjc-runtime/deep-interview-repair.ts +1674 -0
  34. package/src/gjc-runtime/deep-interview-runtime.ts +264 -103
  35. package/src/gjc-runtime/deep-interview-state.ts +916 -4
  36. package/src/gjc-runtime/ralplan-runtime.ts +3 -1
  37. package/src/gjc-runtime/state-writer.ts +166 -2
  38. package/src/gjc-runtime/workflow-manifest.generated.json +386 -1
  39. package/src/gjc-runtime/workflow-manifest.ts +191 -5
  40. package/src/internal-urls/docs-index.generated.ts +3 -2
  41. package/src/modes/components/welcome.ts +10 -2
  42. package/src/modes/interactive-mode.ts +29 -9
  43. package/src/prompts/system/system-prompt.md +1 -0
  44. package/src/runtime-mcp/json-rpc.ts +7 -4
  45. package/src/runtime-mcp/redaction.ts +30 -0
  46. package/src/sdk/broker/session-index.ts +11 -1
  47. package/src/sdk/bus/chat-daemon-control.ts +5 -3
  48. package/src/sdk/bus/telegram-daemon-contract.ts +3 -1
  49. package/src/sdk/bus/telegram-daemon.ts +18 -2
  50. package/src/session/agent-session.ts +86 -0
  51. package/src/session/internal/managed-session-scope.ts +206 -111
  52. package/src/session/internal/managed-session-storage.ts +17 -4
  53. package/src/session/session-manager.ts +96 -33
  54. package/src/session/session-storage.ts +23 -0
  55. package/src/skill-state/active-state.ts +10 -0
  56. package/src/task/executor.ts +13 -5
  57. package/src/tools/ask.ts +1 -0
@@ -735,7 +735,7 @@ async function handleArtifactWrite(args: readonly string[], cwd: string): Promis
735
735
  `refusing to overwrite ralplan ${resolved.stage} stage ${resolved.stageN} at ${existingArtifact.path}: an artifact with different content already exists (existing sha256=${existingArtifact.sha256}, new sha256=${sha256}). Use a new --stage_n to record another pass.`,
736
736
  );
737
737
  }
738
- return buildDeduplicatedResult(resolved, existingArtifact, sha256, cwd);
738
+ return buildDeduplicatedResult(resolved, existingArtifact, sha256, cwd, repositoryBinding);
739
739
  }
740
740
 
741
741
  // Keep run-state `current_phase` coherent with the stage being persisted.
@@ -781,6 +781,7 @@ function buildDeduplicatedResult(
781
781
  existing: ExistingStageArtifact,
782
782
  sha256: string,
783
783
  cwd: string,
784
+ repositoryBinding: RepositoryBinding,
784
785
  ): RalplanCommandResult {
785
786
  const payload: Record<string, unknown> = {
786
787
  run_id: resolved.runId,
@@ -788,6 +789,7 @@ function buildDeduplicatedResult(
788
789
  stage: resolved.stage,
789
790
  stage_n: resolved.stageN,
790
791
  sha256,
792
+ repository_binding: repositoryBinding,
791
793
  created_at: existing.createdAt,
792
794
  deduplicated: true,
793
795
  };
@@ -11,6 +11,7 @@ import {
11
11
  type WorkflowStateMutationOwner,
12
12
  type WorkflowStateReceipt,
13
13
  } from "../skill-state/workflow-state-contract";
14
+ import { validateDeepInterviewV1Envelope } from "./deep-interview-state";
14
15
  import {
15
16
  activeEntryPath as layoutActiveEntryPath,
16
17
  activeSnapshotPath as layoutActiveSnapshotPath,
@@ -77,6 +78,47 @@ export interface WorkflowEnvelopeIntegrityMismatch {
77
78
  expected: string;
78
79
  actual: string;
79
80
  }
81
+ export type WorkflowReceiptVerification =
82
+ | "legacy"
83
+ | "native-valid"
84
+ | "receipt-malformed"
85
+ | "receipt-missing"
86
+ | "checksum-mismatch";
87
+
88
+ export interface GuardedWorkflowEnvelopeTransformOptions extends StateWriterOptions {
89
+ expectedRevision: number;
90
+ /** Additional native schema validation applied to both current and candidate envelopes. */
91
+ validate?: (value: Record<string, unknown>, legacy: boolean) => void;
92
+ transform: (
93
+ current: Record<string, unknown>,
94
+ context: { revision: number; legacy: boolean },
95
+ ) =>
96
+ | { kind: "noop" }
97
+ | { kind: "write"; value: Record<string, unknown> }
98
+ | Promise<{ kind: "noop" } | { kind: "write"; value: Record<string, unknown> }>;
99
+ }
100
+
101
+ export interface GuardedWorkflowEnvelopeWarning {
102
+ code: "DI_POST_COMMIT_AUDIT_FAILED";
103
+ message: string;
104
+ }
105
+
106
+ export type GuardedWorkflowEnvelopeTransformResult =
107
+ | { path: string; written: false; reason: "noop"; revision: number; warnings: [] }
108
+ | {
109
+ path: string;
110
+ written: true;
111
+ revision: number;
112
+ stamped: Record<string, unknown>;
113
+ warnings: GuardedWorkflowEnvelopeWarning[];
114
+ };
115
+
116
+ export class GuardedWorkflowEnvelopeError extends Error {
117
+ constructor(public readonly code: string) {
118
+ super(code);
119
+ this.name = "GuardedWorkflowEnvelopeError";
120
+ }
121
+ }
80
122
 
81
123
  export interface WorkflowTransactionJournal {
82
124
  version: 1;
@@ -108,6 +150,7 @@ export interface StateWriterOptions {
108
150
  receipt?: StateWriterReceiptContext;
109
151
  audit?: StateWriterAuditContext;
110
152
  sourceRevision?: number;
153
+ orderingRevision?: number;
111
154
  /**
112
155
  * Cross-process lock tuning for read-modify-write paths that route through
113
156
  * `withWorkflowStateLock` / `updateJsonAtomic`. Omit for the hardened
@@ -255,6 +298,49 @@ export function workflowEnvelopeContentSha256(value: unknown): string {
255
298
  .update(JSON.stringify(canonicalizeJson(withoutReceiptChecksum(value))))
256
299
  .digest("hex");
257
300
  }
301
+ function isNativeDeepInterviewV1(value: Record<string, unknown>): boolean {
302
+ if (value.skill !== "deep-interview") return false;
303
+ return value.schema_version === 1 || (isPlainObject(value.state) && value.state.schema_version === 1);
304
+ }
305
+
306
+ export function verifyWorkflowEnvelopeReceiptValue(value: unknown, filePath: string): WorkflowReceiptVerification {
307
+ if (!isPlainObject(value)) return "receipt-malformed";
308
+ const native = isNativeDeepInterviewV1(value);
309
+ if (!Object.hasOwn(value, "receipt")) return native ? "receipt-missing" : "legacy";
310
+ if (!isPlainObject(value.receipt) || !isPlainObject(value.receipt.content_sha256)) return "receipt-malformed";
311
+
312
+ const receipt = value.receipt as Record<string, unknown>;
313
+ const checksum = receipt.content_sha256 as Record<string, unknown>;
314
+ if (
315
+ typeof value.skill !== "string" ||
316
+ receipt.version !== 1 ||
317
+ receipt.skill !== value.skill ||
318
+ (receipt.skill !== "deep-interview" &&
319
+ receipt.skill !== "ralplan" &&
320
+ receipt.skill !== "ultragoal" &&
321
+ receipt.skill !== "team") ||
322
+ (receipt.owner !== "gjc-state-cli" && receipt.owner !== "gjc-runtime" && receipt.owner !== "gjc-hook") ||
323
+ typeof receipt.command !== "string" ||
324
+ typeof receipt.state_path !== "string" ||
325
+ typeof receipt.storage_path !== "string" ||
326
+ typeof receipt.mutated_at !== "string" ||
327
+ !Number.isFinite(Date.parse(receipt.mutated_at)) ||
328
+ typeof receipt.fresh_until !== "string" ||
329
+ !Number.isFinite(Date.parse(receipt.fresh_until)) ||
330
+ (receipt.status !== "fresh" && receipt.status !== "stale") ||
331
+ typeof receipt.mutation_id !== "string" ||
332
+ checksum.algorithm !== "sha256" ||
333
+ typeof checksum.value !== "string" ||
334
+ !/^[0-9a-f]{64}$/.test(checksum.value) ||
335
+ typeof checksum.covered_path !== "string" ||
336
+ path.resolve(checksum.covered_path) !== path.resolve(filePath) ||
337
+ typeof checksum.computed_at !== "string" ||
338
+ !Number.isFinite(Date.parse(checksum.computed_at))
339
+ ) {
340
+ return "receipt-malformed";
341
+ }
342
+ return workflowEnvelopeContentSha256(value) === checksum.value ? "native-valid" : "checksum-mismatch";
343
+ }
258
344
 
259
345
  export function stampWorkflowEnvelopeChecksum<T>(value: T, filePath: string, computedAt = new Date().toISOString()): T {
260
346
  if (!value || typeof value !== "object" || Array.isArray(value)) return value;
@@ -421,6 +507,11 @@ function persistedSourceRevision(value: unknown): number {
421
507
  const revision = value.source_state_revision;
422
508
  return typeof revision === "number" && Number.isFinite(revision) ? revision : persistedStateRevision(value);
423
509
  }
510
+ function persistedCommittedModeRevision(value: unknown): number {
511
+ if (!isPlainObject(value)) return 0;
512
+ const revision = value.committed_mode_state_revision;
513
+ return typeof revision === "number" && Number.isFinite(revision) ? revision : 0;
514
+ }
424
515
 
425
516
  function withoutCandidateRevision(value: unknown): unknown {
426
517
  if (!isPlainObject(value)) return value;
@@ -529,7 +620,12 @@ async function writeGuardedResolvedJsonAtomic(
529
620
 
530
621
  const incomingSourceRevision =
531
622
  options.sourceRevision ?? (isPlainObject(value) ? persistedStateRevision(value) : 0);
532
- if (current !== undefined && incomingSourceRevision <= persistedSourceRevision(current)) {
623
+ if (
624
+ current !== undefined &&
625
+ (options.orderingRevision !== undefined
626
+ ? options.orderingRevision <= persistedCommittedModeRevision(current)
627
+ : incomingSourceRevision <= persistedSourceRevision(current))
628
+ ) {
533
629
  return { path: filePath, written: false, reason: "stale-skip", revision: currentRevision };
534
630
  }
535
631
  const next = stampStateRevision(
@@ -563,6 +659,7 @@ export async function writeGuardedWorkflowEnvelopeAtomic(
563
659
  const write = async (): Promise<GuardedWriteResult> => {
564
660
  const current = await readJsonIfPresentTolerant(filePath);
565
661
  const currentRevision = persistedStateRevision(current);
662
+
566
663
  if (options.policy === "source") {
567
664
  if (options.expectedRevision !== undefined && options.expectedRevision !== currentRevision) {
568
665
  throw new StateWriteConflictError(filePath, options.expectedRevision, currentRevision);
@@ -586,9 +683,15 @@ export async function writeGuardedWorkflowEnvelopeAtomic(
586
683
  await maybeAudit(filePath, options);
587
684
  return { path: filePath, written: true, revision: currentRevision + 1, stamped: next };
588
685
  }
686
+
589
687
  const incomingSourceRevision =
590
688
  options.sourceRevision ?? (isPlainObject(value) ? persistedStateRevision(value) : 0);
591
- if (current !== undefined && incomingSourceRevision <= persistedSourceRevision(current)) {
689
+ if (
690
+ current !== undefined &&
691
+ (options.orderingRevision !== undefined
692
+ ? options.orderingRevision <= persistedCommittedModeRevision(current)
693
+ : incomingSourceRevision <= persistedSourceRevision(current))
694
+ ) {
592
695
  return { path: filePath, written: false, reason: "stale-skip", revision: currentRevision };
593
696
  }
594
697
  const next = stampWorkflowEnvelopeRevisionAndChecksum(
@@ -612,6 +715,67 @@ export async function writeGuardedWorkflowEnvelopeAtomic(
612
715
  };
613
716
  return options.lockHeld ? write() : lockResolvedWorkflowTarget(filePath, write, options.lock);
614
717
  }
718
+ export async function transformGuardedWorkflowEnvelopeAtomic(
719
+ targetPath: string,
720
+ options: GuardedWorkflowEnvelopeTransformOptions,
721
+ ): Promise<GuardedWorkflowEnvelopeTransformResult> {
722
+ const filePath = resolveGjcTarget(targetPath, cwdForOptions(options));
723
+ return lockResolvedWorkflowTarget(
724
+ filePath,
725
+ async () => {
726
+ const read = await readExistingStateForMutation(filePath);
727
+ if (read.kind === "absent") throw new GuardedWorkflowEnvelopeError("DI_STATE_ABSENT");
728
+ if (read.kind === "corrupt") throw new GuardedWorkflowEnvelopeError("DI_STATE_CORRUPT");
729
+ const receipt = verifyWorkflowEnvelopeReceiptValue(read.value, filePath);
730
+ if (receipt === "receipt-malformed") throw new GuardedWorkflowEnvelopeError("DI_RECEIPT_MALFORMED");
731
+ if (receipt === "receipt-missing") throw new GuardedWorkflowEnvelopeError("DI_RECEIPT_MISSING");
732
+ if (receipt === "checksum-mismatch") throw new GuardedWorkflowEnvelopeError("DI_RECEIPT_CHECKSUM_MISMATCH");
733
+ const legacy = receipt === "legacy";
734
+ try {
735
+ if (isNativeDeepInterviewV1(read.value)) validateDeepInterviewV1Envelope(read.value);
736
+ options.validate?.(read.value, legacy);
737
+ } catch {
738
+ throw new GuardedWorkflowEnvelopeError("DI_STATE_SCHEMA_INVALID");
739
+ }
740
+ const phase = read.value.current_phase;
741
+ if (phase === "complete" || phase === "handoff" || read.value.active === false) {
742
+ throw new GuardedWorkflowEnvelopeError("DI_PHASE_NOT_REPAIRABLE");
743
+ }
744
+ const revision = persistedStateRevision(read.value);
745
+ if (revision !== options.expectedRevision) throw new GuardedWorkflowEnvelopeError("DI_REVISION_CONFLICT");
746
+ const transformed = await options.transform(read.value, { revision, legacy });
747
+ if (transformed.kind === "noop")
748
+ return { path: filePath, written: false, reason: "noop", revision, warnings: [] };
749
+ try {
750
+ if (isNativeDeepInterviewV1(transformed.value)) validateDeepInterviewV1Envelope(transformed.value);
751
+ options.validate?.(transformed.value, false);
752
+ } catch {
753
+ throw new GuardedWorkflowEnvelopeError("DI_STATE_SCHEMA_INVALID");
754
+ }
755
+ const stamped = stampWorkflowEnvelopeRevisionAndChecksum(
756
+ transformed.value,
757
+ filePath,
758
+ revision + 1,
759
+ undefined,
760
+ options,
761
+ ) as Record<string, unknown>;
762
+ const parsed = RequiredOnWriteEnvelopeSchema.safeParse(stamped);
763
+ if (!parsed.success) throw new GuardedWorkflowEnvelopeError("DI_STATE_SCHEMA_INVALID");
764
+ await atomicWrite(filePath, jsonText(stamped));
765
+ const warnings: GuardedWorkflowEnvelopeWarning[] = [];
766
+ try {
767
+ await maybeAudit(filePath, options);
768
+ } catch (error) {
769
+ warnings.push({
770
+ code: "DI_POST_COMMIT_AUDIT_FAILED",
771
+ message: error instanceof Error ? error.message : String(error),
772
+ });
773
+ }
774
+ return { path: filePath, written: true, revision: revision + 1, stamped, warnings };
775
+ },
776
+ options.lock,
777
+ );
778
+ }
615
779
 
616
780
  export async function writeJsonAtomic(
617
781
  targetPath: string,
@@ -212,6 +212,21 @@
212
212
  "name": "threshold-source",
213
213
  "type": "string"
214
214
  },
215
+ {
216
+ "appliesToVerbs": [
217
+ "kickoff"
218
+ ],
219
+ "name": "trace",
220
+ "type": "boolean"
221
+ },
222
+ {
223
+ "appliesToVerbs": [
224
+ "kickoff",
225
+ "write-spec"
226
+ ],
227
+ "name": "json",
228
+ "type": "boolean"
229
+ },
215
230
  {
216
231
  "appliesToVerbs": [
217
232
  "write-spec"
@@ -256,11 +271,333 @@
256
271
  },
257
272
  {
258
273
  "appliesToVerbs": [
259
- "write-spec"
274
+ "draft create"
275
+ ],
276
+ "name": "session-id",
277
+ "required": true,
278
+ "type": "string"
279
+ },
280
+ {
281
+ "appliesToVerbs": [
282
+ "draft create"
283
+ ],
284
+ "enumValues": [
285
+ "initialize-context",
286
+ "confirm-topology",
287
+ "record-answer",
288
+ "apply-round-result"
289
+ ],
290
+ "name": "for",
291
+ "required": true,
292
+ "type": "enum"
293
+ },
294
+ {
295
+ "appliesToVerbs": [
296
+ "draft create"
297
+ ],
298
+ "name": "round-key",
299
+ "type": "string"
300
+ },
301
+ {
302
+ "appliesToVerbs": [
303
+ "draft create"
304
+ ],
305
+ "name": "round",
306
+ "type": "number"
307
+ },
308
+ {
309
+ "appliesToVerbs": [
310
+ "draft create"
311
+ ],
312
+ "name": "question-id",
313
+ "type": "string"
314
+ },
315
+ {
316
+ "appliesToVerbs": [
317
+ "draft create"
318
+ ],
319
+ "name": "round-id",
320
+ "type": "string"
321
+ },
322
+ {
323
+ "appliesToVerbs": [
324
+ "draft create"
325
+ ],
326
+ "name": "component-id",
327
+ "type": "string"
328
+ },
329
+ {
330
+ "appliesToVerbs": [
331
+ "draft create"
332
+ ],
333
+ "name": "dimension",
334
+ "type": "string"
335
+ },
336
+ {
337
+ "appliesToVerbs": [
338
+ "draft edit",
339
+ "draft show",
340
+ "draft check",
341
+ "draft rebase",
342
+ "draft discard",
343
+ "initialize-context",
344
+ "confirm-topology",
345
+ "record-answer",
346
+ "apply-round-result"
347
+ ],
348
+ "name": "draft-id",
349
+ "required": true,
350
+ "type": "string"
351
+ },
352
+ {
353
+ "appliesToVerbs": [
354
+ "draft edit",
355
+ "draft rebase",
356
+ "draft discard",
357
+ "initialize-context",
358
+ "confirm-topology",
359
+ "record-answer",
360
+ "apply-round-result"
361
+ ],
362
+ "name": "expected-draft-revision",
363
+ "required": true,
364
+ "type": "number"
365
+ },
366
+ {
367
+ "appliesToVerbs": [
368
+ "draft edit"
369
+ ],
370
+ "enumValues": [
371
+ "set",
372
+ "append",
373
+ "remove"
374
+ ],
375
+ "name": "op",
376
+ "required": true,
377
+ "type": "enum"
378
+ },
379
+ {
380
+ "appliesToVerbs": [
381
+ "draft edit"
382
+ ],
383
+ "name": "path",
384
+ "required": true,
385
+ "type": "string"
386
+ },
387
+ {
388
+ "appliesToVerbs": [
389
+ "draft edit"
390
+ ],
391
+ "name": "value",
392
+ "type": "string"
393
+ },
394
+ {
395
+ "appliesToVerbs": [
396
+ "draft edit"
397
+ ],
398
+ "name": "value-file",
399
+ "type": "string"
400
+ },
401
+ {
402
+ "appliesToVerbs": [
403
+ "draft edit"
404
+ ],
405
+ "name": "null",
406
+ "type": "boolean"
407
+ },
408
+ {
409
+ "appliesToVerbs": [
410
+ "draft rebase"
411
+ ],
412
+ "name": "to-state-revision",
413
+ "required": true,
414
+ "type": "number"
415
+ },
416
+ {
417
+ "appliesToVerbs": [
418
+ "draft create",
419
+ "draft edit",
420
+ "draft show",
421
+ "draft check",
422
+ "draft rebase",
423
+ "draft discard",
424
+ "initialize-context",
425
+ "confirm-topology",
426
+ "record-answer",
427
+ "apply-round-result",
428
+ "inspect",
429
+ "sanity-check"
260
430
  ],
261
431
  "name": "json",
432
+ "required": true,
262
433
  "type": "boolean"
263
434
  },
435
+ {
436
+ "appliesToVerbs": [
437
+ "inspect",
438
+ "sanity-check"
439
+ ],
440
+ "name": "session-id",
441
+ "required": true,
442
+ "type": "string"
443
+ },
444
+ {
445
+ "appliesToVerbs": [
446
+ "initialize-context",
447
+ "confirm-topology",
448
+ "record-answer",
449
+ "apply-round-result"
450
+ ],
451
+ "compatibilityOnly": true,
452
+ "name": "session-id",
453
+ "required": true,
454
+ "type": "string"
455
+ },
456
+ {
457
+ "appliesToVerbs": [
458
+ "initialize-context",
459
+ "confirm-topology",
460
+ "record-answer",
461
+ "apply-round-result"
462
+ ],
463
+ "compatibilityOnly": true,
464
+ "name": "schema-version",
465
+ "required": true,
466
+ "type": "number"
467
+ },
468
+ {
469
+ "appliesToVerbs": [
470
+ "initialize-context",
471
+ "confirm-topology",
472
+ "record-answer",
473
+ "apply-round-result"
474
+ ],
475
+ "compatibilityOnly": true,
476
+ "name": "expected-revision",
477
+ "required": true,
478
+ "type": "number"
479
+ },
480
+ {
481
+ "appliesToVerbs": [
482
+ "initialize-context",
483
+ "confirm-topology"
484
+ ],
485
+ "compatibilityOnly": true,
486
+ "name": "input-json",
487
+ "required": true,
488
+ "type": "object"
489
+ },
490
+ {
491
+ "appliesToVerbs": [
492
+ "record-answer",
493
+ "apply-round-result"
494
+ ],
495
+ "compatibilityOnly": true,
496
+ "name": "round",
497
+ "required": true,
498
+ "type": "number"
499
+ },
500
+ {
501
+ "appliesToVerbs": [
502
+ "record-answer",
503
+ "apply-round-result"
504
+ ],
505
+ "compatibilityOnly": true,
506
+ "name": "question-id",
507
+ "required": true,
508
+ "type": "string"
509
+ },
510
+ {
511
+ "appliesToVerbs": [
512
+ "record-answer",
513
+ "apply-round-result"
514
+ ],
515
+ "compatibilityOnly": true,
516
+ "name": "round-id",
517
+ "type": "string"
518
+ },
519
+ {
520
+ "appliesToVerbs": [
521
+ "record-answer"
522
+ ],
523
+ "compatibilityOnly": true,
524
+ "name": "component-id",
525
+ "type": "string"
526
+ },
527
+ {
528
+ "appliesToVerbs": [
529
+ "record-answer"
530
+ ],
531
+ "compatibilityOnly": true,
532
+ "name": "dimension",
533
+ "type": "string"
534
+ },
535
+ {
536
+ "appliesToVerbs": [
537
+ "record-answer"
538
+ ],
539
+ "compatibilityOnly": true,
540
+ "name": "answer-json",
541
+ "required": true,
542
+ "type": "object"
543
+ },
544
+ {
545
+ "appliesToVerbs": [
546
+ "record-answer"
547
+ ],
548
+ "compatibilityOnly": true,
549
+ "name": "question-json",
550
+ "required": true,
551
+ "type": "string"
552
+ },
553
+ {
554
+ "appliesToVerbs": [
555
+ "apply-round-result"
556
+ ],
557
+ "compatibilityOnly": true,
558
+ "name": "result-json",
559
+ "required": true,
560
+ "type": "object"
561
+ },
562
+ {
563
+ "appliesToVerbs": [
564
+ "inspect"
565
+ ],
566
+ "enumValues": [
567
+ "summary",
568
+ "recent-scored",
569
+ "pending",
570
+ "round",
571
+ "topology",
572
+ "facts",
573
+ "triggers",
574
+ "floor"
575
+ ],
576
+ "name": "selector",
577
+ "required": true,
578
+ "type": "enum"
579
+ },
580
+ {
581
+ "appliesToVerbs": [
582
+ "inspect"
583
+ ],
584
+ "name": "round-key",
585
+ "type": "string"
586
+ },
587
+ {
588
+ "appliesToVerbs": [
589
+ "inspect"
590
+ ],
591
+ "name": "cursor",
592
+ "type": "string"
593
+ },
594
+ {
595
+ "appliesToVerbs": [
596
+ "inspect"
597
+ ],
598
+ "name": "limit",
599
+ "type": "number"
600
+ },
264
601
  {
265
602
  "name": "args",
266
603
  "planned": true,
@@ -305,6 +642,54 @@
305
642
  "name": "write-spec",
306
643
  "surface": "command-flag"
307
644
  },
645
+ {
646
+ "name": "draft create",
647
+ "surface": "draft-action"
648
+ },
649
+ {
650
+ "name": "draft edit",
651
+ "surface": "draft-action"
652
+ },
653
+ {
654
+ "name": "draft show",
655
+ "surface": "draft-action"
656
+ },
657
+ {
658
+ "name": "draft check",
659
+ "surface": "draft-action"
660
+ },
661
+ {
662
+ "name": "draft rebase",
663
+ "surface": "draft-action"
664
+ },
665
+ {
666
+ "name": "draft discard",
667
+ "surface": "draft-action"
668
+ },
669
+ {
670
+ "name": "initialize-context",
671
+ "surface": "command-positional"
672
+ },
673
+ {
674
+ "name": "confirm-topology",
675
+ "surface": "command-positional"
676
+ },
677
+ {
678
+ "name": "record-answer",
679
+ "surface": "command-positional"
680
+ },
681
+ {
682
+ "name": "apply-round-result",
683
+ "surface": "command-positional"
684
+ },
685
+ {
686
+ "name": "inspect",
687
+ "surface": "command-positional"
688
+ },
689
+ {
690
+ "name": "sanity-check",
691
+ "surface": "command-positional"
692
+ },
308
693
  {
309
694
  "name": "graph",
310
695
  "planned": true,