@starci/skills 1.1.0 → 1.2.0

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 (75) hide show
  1. package/INDEX.md +3 -1
  2. package/INDEX.vi.md +3 -1
  3. package/README.md +6 -1
  4. package/README.vi.md +6 -1
  5. package/knowledge/ui/presentation/INDEX.md +5 -0
  6. package/knowledge/ui/presentation/INDEX.vi.md +1 -0
  7. package/knowledge/ui/presentation/radius.md +183 -0
  8. package/knowledge/ui/presentation/radius.vi.md +182 -0
  9. package/operators/INDEX.md +5 -5
  10. package/operators/INDEX.vi.md +5 -5
  11. package/operators/architecture-decide/operator.md +27 -4
  12. package/operators/architecture-decide/operator.vi.md +23 -4
  13. package/operators/architecture-decide/self-test.mjs +18 -1
  14. package/operators/architecture-decide/validate.mjs +29 -1
  15. package/operators/backend-source-apply/operator.md +197 -182
  16. package/operators/backend-source-apply/operator.vi.md +190 -178
  17. package/operators/backend-source-apply/self-test.mjs +257 -257
  18. package/operators/backend-source-apply/validate.mjs +240 -240
  19. package/operators/business-decide/self-test.mjs +2 -1
  20. package/operators/business-decide/validate.mjs +3 -0
  21. package/operators/content-generate/self-test.mjs +1 -1
  22. package/operators/frontend-direction-decide/self-test.mjs +1 -1
  23. package/operators/frontend-presentation-resolve/operator.md +6 -0
  24. package/operators/frontend-presentation-resolve/operator.vi.md +6 -0
  25. package/operators/frontend-presentation-resolve/self-test.mjs +6 -5
  26. package/operators/frontend-presentation-resolve/validate.mjs +30 -6
  27. package/operators/frontend-source-apply/operator.md +3 -1
  28. package/operators/frontend-source-apply/operator.vi.md +3 -1
  29. package/operators/frontend-source-apply/self-test.mjs +1 -1
  30. package/operators/frontend-surface-audit/self-test.mjs +1 -1
  31. package/operators/git-publish/self-test.mjs +1 -1
  32. package/operators/platform-operate/self-test.mjs +1 -1
  33. package/operators/quality-verify/operator.md +5 -1
  34. package/operators/quality-verify/operator.vi.md +5 -1
  35. package/operators/quality-verify/self-test.mjs +15 -2
  36. package/operators/quality-verify/validate.mjs +21 -1
  37. package/operators/release-deploy/self-test.mjs +235 -235
  38. package/operators/uat-verify/operator.md +20 -6
  39. package/operators/uat-verify/operator.vi.md +21 -7
  40. package/operators/uat-verify/self-test.mjs +6 -5
  41. package/operators/uat-verify/validate.mjs +10 -4
  42. package/operators/workspace-bind/operator.md +18 -4
  43. package/operators/workspace-bind/operator.vi.md +16 -4
  44. package/operators/workspace-bind/self-test.mjs +3 -1
  45. package/operators/workspace-bind/validate.mjs +1 -0
  46. package/package.json +1 -1
  47. package/readiness/initialization/workspaces/local-route.schema.json +1 -1
  48. package/resources/orchestrator.json +14 -8
  49. package/routing.json +2 -1
  50. package/scripts/validate-request.mjs +12 -1
  51. package/scripts/validate-response.mjs +14 -3
  52. package/scripts/validate-step.mjs +2 -1
  53. package/scripts/validate-workflows.mjs +8 -1
  54. package/templates/kinds/architecture-decision.contract.json +1 -0
  55. package/templates/kinds/architecture-decision.skeleton.md +6 -0
  56. package/templates/kinds/backend-source-application.contract.json +1 -1
  57. package/templates/kinds/backend-source-application.skeleton.md +1 -1
  58. package/templates/kinds/frontend-presentation-resolution.contract.json +1 -1
  59. package/templates/kinds/frontend-presentation-resolution.skeleton.md +1 -0
  60. package/templates/kinds/mutations.schema.json +65 -65
  61. package/templates/kinds/route.schema.json +4 -2
  62. package/templates/kinds/stack-model.schema.json +23 -1
  63. package/templates/kinds/workspace-route-binding.contract.json +2 -2
  64. package/templates/step/response.schema.json +10 -0
  65. package/templates/step/state.schema.json +205 -0
  66. package/workflows/README.md +3 -0
  67. package/workflows/README.vi.md +3 -0
  68. package/workflows/backend-feature.json +26 -5
  69. package/workflows/content-unit.json +4 -1
  70. package/workflows/frontend-new-surface.json +15 -5
  71. package/workflows/frontend-reconstruct.json +10 -4
  72. package/workflows/frontend-refine.json +10 -4
  73. package/workflows/frontend-with-uat.json +15 -3
  74. package/workflows/full-feature.json +31 -8
  75. package/workflows/release.json +7 -1
@@ -1,65 +1,65 @@
1
- {
2
- "$id": "kind:mutations",
3
- "title": "Every mutation one source-writing step made or planned, the contract it filled, and the single commit that carries them on the session branch; under mode dry the commit is null and the record is a plan.",
4
- "type": "object",
5
- "additionalProperties": false,
6
- "required": ["mode", "contractFingerprint", "base", "branch", "commit", "operations", "changes"],
7
- "properties": {
8
- "mode": { "enum": ["apply", "dry"] },
9
- "contractFingerprint": { "$ref": "#/$defs/hash" },
10
- "base": { "$ref": "#/$defs/gitHead" },
11
- "branch": { "type": "string", "pattern": "^session/[A-Za-z0-9._-]+$" },
12
- "commit": { "$ref": "#/$defs/nullableGitHead" },
13
- "operations": {
14
- "type": "array",
15
- "minItems": 1,
16
- "maxItems": 64,
17
- "items": { "$ref": "#/$defs/operation" }
18
- },
19
- "changes": {
20
- "type": "array",
21
- "minItems": 1,
22
- "maxItems": 256,
23
- "items": { "$ref": "#/$defs/change" }
24
- }
25
- },
26
- "$defs": {
27
- "hash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
28
- "nullableHash": { "oneOf": [{ "$ref": "#/$defs/hash" }, { "type": "null" }] },
29
- "gitHead": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
30
- "nullableGitHead": { "oneOf": [{ "$ref": "#/$defs/gitHead" }, { "type": "null" }] },
31
- "identifier": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
32
- "facet": { "enum": ["transport", "writer", "store", "transaction", "idempotency", "migration", "exception-identity", "authorization", "concurrency"] },
33
- "proofKind": { "enum": ["unit", "integration", "migration-replay", "conformance-read", "runtime-probe"] },
34
- "operation": {
35
- "type": "object",
36
- "additionalProperties": false,
37
- "required": ["operationId", "name", "transport", "writerRef", "storeRefs", "transactionBoundary", "idempotencyKind", "migrationRefs", "authorityDecisionIds", "facets", "proofKinds"],
38
- "properties": {
39
- "operationId": { "$ref": "#/$defs/identifier" },
40
- "name": { "type": "string", "minLength": 1, "maxLength": 256 },
41
- "transport": { "enum": ["graphql-mutation", "graphql-query", "rest", "worker", "cron", "event-consumer"] },
42
- "writerRef": { "type": "string", "minLength": 1, "maxLength": 1024 },
43
- "storeRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
44
- "transactionBoundary": { "enum": ["single-transaction", "per-item", "read-only", "none"] },
45
- "idempotencyKind": { "enum": ["none", "natural-key", "request-token", "event-id"] },
46
- "migrationRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
47
- "authorityDecisionIds": { "type": "array", "minItems": 1, "maxItems": 64, "items": { "type": "string", "pattern": "^BA-[0-9]+$" } },
48
- "facets": { "type": "array", "minItems": 1, "maxItems": 16, "items": { "$ref": "#/$defs/facet" } },
49
- "proofKinds": { "type": "array", "minItems": 1, "maxItems": 16, "items": { "$ref": "#/$defs/proofKind" } }
50
- }
51
- },
52
- "change": {
53
- "type": "object",
54
- "additionalProperties": false,
55
- "required": ["path", "change", "operationId", "beforeHash", "afterHash"],
56
- "properties": {
57
- "path": { "type": "string", "minLength": 1, "maxLength": 1024 },
58
- "change": { "enum": ["added", "modified", "deleted"] },
59
- "operationId": { "$ref": "#/$defs/identifier" },
60
- "beforeHash": { "$ref": "#/$defs/nullableHash" },
61
- "afterHash": { "$ref": "#/$defs/nullableHash" }
62
- }
63
- }
64
- }
65
- }
1
+ {
2
+ "$id": "kind:mutations",
3
+ "title": "Every mutation one source-writing step made or planned, the contract it filled, and the single commit that carries them on the session branch; under mode dry the commit is null and the record is a plan.",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": ["mode", "contractFingerprint", "base", "branch", "commit", "operations", "changes"],
7
+ "properties": {
8
+ "mode": { "enum": ["apply", "dry"] },
9
+ "contractFingerprint": { "$ref": "#/$defs/hash" },
10
+ "base": { "$ref": "#/$defs/gitHead" },
11
+ "branch": { "type": "string", "pattern": "^session/[A-Za-z0-9._-]+$" },
12
+ "commit": { "$ref": "#/$defs/nullableGitHead" },
13
+ "operations": {
14
+ "type": "array",
15
+ "minItems": 1,
16
+ "maxItems": 64,
17
+ "items": { "$ref": "#/$defs/operation" }
18
+ },
19
+ "changes": {
20
+ "type": "array",
21
+ "minItems": 1,
22
+ "maxItems": 256,
23
+ "items": { "$ref": "#/$defs/change" }
24
+ }
25
+ },
26
+ "$defs": {
27
+ "hash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
28
+ "nullableHash": { "oneOf": [{ "$ref": "#/$defs/hash" }, { "type": "null" }] },
29
+ "gitHead": { "type": "string", "pattern": "^[0-9a-f]{40}$" },
30
+ "nullableGitHead": { "oneOf": [{ "$ref": "#/$defs/gitHead" }, { "type": "null" }] },
31
+ "identifier": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
32
+ "facet": { "enum": ["transport", "writer", "store", "transaction", "idempotency", "migration", "exception-identity", "authorization", "concurrency"] },
33
+ "proofKind": { "enum": ["unit", "integration", "migration-replay", "conformance-read", "runtime-probe"] },
34
+ "operation": {
35
+ "type": "object",
36
+ "additionalProperties": false,
37
+ "required": ["operationId", "name", "transport", "writerRef", "storeRefs", "transactionBoundary", "idempotencyKind", "migrationRefs", "authorityDimensionIds", "facets", "proofKinds"],
38
+ "properties": {
39
+ "operationId": { "$ref": "#/$defs/identifier" },
40
+ "name": { "type": "string", "minLength": 1, "maxLength": 256 },
41
+ "transport": { "enum": ["graphql-mutation", "graphql-query", "rest", "worker", "cron", "event-consumer"] },
42
+ "writerRef": { "type": "string", "minLength": 1, "maxLength": 1024 },
43
+ "storeRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
44
+ "transactionBoundary": { "enum": ["single-transaction", "per-item", "read-only", "none"] },
45
+ "idempotencyKind": { "enum": ["none", "natural-key", "request-token", "event-id"] },
46
+ "migrationRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
47
+ "authorityDimensionIds": { "type": "array", "minItems": 1, "maxItems": 64, "items": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" } },
48
+ "facets": { "type": "array", "minItems": 1, "maxItems": 16, "items": { "$ref": "#/$defs/facet" } },
49
+ "proofKinds": { "type": "array", "minItems": 1, "maxItems": 16, "items": { "$ref": "#/$defs/proofKind" } }
50
+ }
51
+ },
52
+ "change": {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "required": ["path", "change", "operationId", "beforeHash", "afterHash"],
56
+ "properties": {
57
+ "path": { "type": "string", "minLength": 1, "maxLength": 1024 },
58
+ "change": { "enum": ["added", "modified", "deleted"] },
59
+ "operationId": { "$ref": "#/$defs/identifier" },
60
+ "beforeHash": { "$ref": "#/$defs/nullableHash" },
61
+ "afterHash": { "$ref": "#/$defs/nullableHash" }
62
+ }
63
+ }
64
+ }
65
+ }
@@ -34,10 +34,12 @@
34
34
  "minLength": 1
35
35
  },
36
36
  "routeFingerprint": {
37
- "$ref": "#/$defs/fingerprint"
37
+ "$ref": "#/$defs/fingerprint",
38
+ "description": "sha256 over the bytes of the portable declaration followed by the bytes of the hydrated route, each exactly as stored on disk, with no normalisation."
38
39
  },
39
40
  "identityFingerprint": {
40
- "$ref": "#/$defs/fingerprint"
41
+ "$ref": "#/$defs/fingerprint",
42
+ "description": "sha256 over the bytes of .workspaces/device-state.json, exactly as stored on disk, with no normalisation."
41
43
  },
42
44
  "sourceHead": {
43
45
  "$ref": "#/$defs/gitHead"
@@ -2,7 +2,7 @@
2
2
  "$id": "kind:stack-model",
3
3
  "type": "object",
4
4
  "additionalProperties": false,
5
- "required": ["decisionId", "selectedAlternativeId", "alternatives", "boundaries", "stores", "components"],
5
+ "required": ["decisionId", "selectedAlternativeId", "alternatives", "boundaries", "stores", "components", "operations"],
6
6
  "$defs": {
7
7
  "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
8
8
  "verdict": {
@@ -70,6 +70,28 @@
70
70
  }
71
71
  }
72
72
  },
73
+ "operations": {
74
+ "type": "array",
75
+ "minItems": 1,
76
+ "maxItems": 64,
77
+ "description": "One row per write this decision commits to. The implementation restates these unchanged as the operations of its mutation record; it may not add one, and it may not choose its own writer.",
78
+ "items": {
79
+ "type": "object",
80
+ "additionalProperties": false,
81
+ "required": ["operationId", "name", "transport", "writerRef", "storeRefs", "transactionBoundary", "idempotencyKind", "migrationRefs", "authorityDimensionIds"],
82
+ "properties": {
83
+ "operationId": { "$ref": "#/$defs/id" },
84
+ "name": { "type": "string", "minLength": 1, "maxLength": 256 },
85
+ "transport": { "enum": ["graphql-mutation", "graphql-query", "rest", "worker", "cron", "event-consumer"] },
86
+ "writerRef": { "type": "string", "minLength": 1, "maxLength": 1024, "description": "The one file path this operator names: the implementation may not choose its own writer." },
87
+ "storeRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
88
+ "transactionBoundary": { "enum": ["single-transaction", "per-item", "read-only", "none"] },
89
+ "idempotencyKind": { "enum": ["none", "natural-key", "request-token", "event-id"] },
90
+ "migrationRefs": { "type": "array", "maxItems": 64, "items": { "type": "string", "minLength": 1 } },
91
+ "authorityDimensionIds": { "type": "array", "minItems": 1, "maxItems": 64, "items": { "$ref": "#/$defs/id" }, "description": "The coverage-matrix dimensions of the bound business head this operation implements." }
92
+ }
93
+ }
94
+ },
73
95
  "components": {
74
96
  "type": "array",
75
97
  "minItems": 1,
@@ -5,8 +5,8 @@
5
5
  { "heading": "^## Binding$", "table": "| Field | Value |", "rows": ["Project", "Role", "Portable route", "Hydrated route", "Source head"], "cell": { "Value": "\\S" } },
6
6
  { "heading": "^## Checkout$", "table": "| Field | Value |", "rows": ["Disk path", "Git root", "Git repository", "Branch", "Repository kind", "Directory", "Source head", "Mutation readiness", "Businesses root"], "cell": { "Value": "\\S" } },
7
7
  { "heading": "^## Policy$", "table": "| Field | Value |", "rows": ["Worktree branches", "Mutation branch"], "cell": { "Value": "\\S" } },
8
- { "heading": "^## Write roots$", "table": "| Path | Why |", "minRows": 1, "cell": { "Path": "\\S", "Why": "\\S" } },
8
+ { "heading": "^## Write roots$", "table": "| Path | Why |", "cell": { "Path": "\\S", "Why": "\\S" } },
9
9
  { "heading": "^## Runtime$", "table": "| Field | Value |", "cell": { "Value": "\\S" } },
10
- { "heading": "^## Findings$", "table": "| Code | Subject | Statement |", "minRows": 1, "cell": { "Code": "^`(ROUTE_HYDRATED_FROM_PORTABLE|RUNTIME_CONSUMED_NOT_OWNED|IDENTITY_ROSTER_SEALED|PROVENANCE_HEAD_BOUND|CACHED_ROUTE_REUSED|WORKTREE_BRANCH_FORBIDDEN)`$", "Subject": "\\S", "Statement": "\\S" } }
10
+ { "heading": "^## Findings$", "table": "| Code | Subject | Statement |", "minRows": 1, "cell": { "Code": "^`(ROUTE_HYDRATED_FROM_PORTABLE|RUNTIME_CONSUMED_NOT_OWNED|IDENTITY_ROSTER_SEALED|PROVENANCE_HEAD_BOUND|CACHED_ROUTE_REUSED|WORKTREE_BRANCH_FORBIDDEN|WORKTREE_BRANCH_SESSION_ONLY)`$", "Subject": "\\S", "Statement": "\\S" } }
11
11
  ]
12
12
  }
@@ -109,6 +109,16 @@
109
109
  "minLength": 1,
110
110
  "maxLength": 2000,
111
111
  "description": "One paragraph for a person: why the branch blocked or waits, when the kind files could not be written"
112
+ },
113
+ "boundProfile": {
114
+ "type": "string",
115
+ "pattern": "^[a-z][a-z-]*$",
116
+ "description": "The profile operator.json binds; recorded with ranProfile when the processor ran a stand-in (resources/orchestrator.json#profileEquivalents)"
117
+ },
118
+ "ranProfile": {
119
+ "type": "string",
120
+ "pattern": "^[a-z][a-z-]*$",
121
+ "description": "The profile that actually ran the branch"
112
122
  }
113
123
  },
114
124
  "allOf": [
@@ -0,0 +1,205 @@
1
+ {
2
+ "$id": "step:state",
3
+ "description": "state.json at the session root; the orchestrator writes it, no agent does. Documented in resources/orchestrator.json#session.manifest.",
4
+ "type": "object",
5
+ "additionalProperties": false,
6
+ "required": [
7
+ "id",
8
+ "project",
9
+ "startedAt",
10
+ "status",
11
+ "chain",
12
+ "steps",
13
+ "requestHashes"
14
+ ],
15
+ "properties": {
16
+ "id": {
17
+ "type": "string",
18
+ "minLength": 1
19
+ },
20
+ "project": {
21
+ "type": "string",
22
+ "minLength": 1
23
+ },
24
+ "workflow": {
25
+ "type": [
26
+ "string",
27
+ "null"
28
+ ]
29
+ },
30
+ "startedAt": {
31
+ "type": "string",
32
+ "minLength": 1
33
+ },
34
+ "status": {
35
+ "enum": [
36
+ "running",
37
+ "blocked",
38
+ "done",
39
+ "stopped"
40
+ ]
41
+ },
42
+ "chain": {
43
+ "type": "array",
44
+ "minItems": 1,
45
+ "items": {
46
+ "type": "array",
47
+ "minItems": 1,
48
+ "items": {
49
+ "type": "string",
50
+ "pattern": "^[0-9]+/[0-9]+$"
51
+ }
52
+ }
53
+ },
54
+ "steps": {
55
+ "type": "object",
56
+ "additionalProperties": {
57
+ "type": "string",
58
+ "pattern": "^[a-z]+(?:\\.[a-z]+)+$"
59
+ }
60
+ },
61
+ "current": {
62
+ "type": [
63
+ "string",
64
+ "null"
65
+ ],
66
+ "pattern": "^[0-9]+/[0-9]+$"
67
+ },
68
+ "leases": {
69
+ "type": "object",
70
+ "additionalProperties": {
71
+ "type": "object",
72
+ "additionalProperties": false,
73
+ "required": [
74
+ "agent",
75
+ "holds"
76
+ ],
77
+ "properties": {
78
+ "agent": {
79
+ "type": "string"
80
+ },
81
+ "holds": {
82
+ "type": "array",
83
+ "items": {
84
+ "type": "string"
85
+ }
86
+ }
87
+ }
88
+ }
89
+ },
90
+ "requestHashes": {
91
+ "type": "object",
92
+ "additionalProperties": {
93
+ "type": "string",
94
+ "pattern": "^sha256:[0-9a-f]{64}$"
95
+ }
96
+ },
97
+ "resumes": {
98
+ "description": "branch \"N/M\" that re-enters a blocked branch: which one, and the stop it answered",
99
+ "type": "object",
100
+ "additionalProperties": {
101
+ "type": "object",
102
+ "additionalProperties": false,
103
+ "required": [
104
+ "resumes",
105
+ "stop"
106
+ ],
107
+ "properties": {
108
+ "resumes": {
109
+ "type": "string",
110
+ "pattern": "^[0-9]+/[0-9]+$"
111
+ },
112
+ "stop": {
113
+ "type": "string",
114
+ "pattern": "^[A-Z][A-Z0-9_]+$"
115
+ }
116
+ }
117
+ }
118
+ },
119
+ "stoppedAt": {
120
+ "description": "where the session ended: a terminating stop, a response that failed a validator (stop null), or a person",
121
+ "type": "object",
122
+ "additionalProperties": false,
123
+ "required": [
124
+ "branch",
125
+ "operator",
126
+ "stop",
127
+ "why"
128
+ ],
129
+ "properties": {
130
+ "branch": {
131
+ "type": "string",
132
+ "pattern": "^[0-9]+/[0-9]+$"
133
+ },
134
+ "operator": {
135
+ "type": "string"
136
+ },
137
+ "stop": {
138
+ "type": [
139
+ "string",
140
+ "null"
141
+ ],
142
+ "pattern": "^[A-Z][A-Z0-9_]+$"
143
+ },
144
+ "domain": {
145
+ "type": [
146
+ "string",
147
+ "null"
148
+ ]
149
+ },
150
+ "route": {
151
+ "type": [
152
+ "string",
153
+ "null"
154
+ ]
155
+ },
156
+ "why": {
157
+ "type": "string",
158
+ "minLength": 1
159
+ }
160
+ }
161
+ },
162
+ "substitutions": {
163
+ "description": "codes the orchestrator read as UNKNOWN_STOP: branch -> the code the agent wrote",
164
+ "type": "object",
165
+ "additionalProperties": {
166
+ "type": "string"
167
+ }
168
+ },
169
+ "transitions": {
170
+ "type": "array",
171
+ "items": {
172
+ "type": "object",
173
+ "additionalProperties": false,
174
+ "required": [
175
+ "at",
176
+ "branch",
177
+ "event"
178
+ ],
179
+ "properties": {
180
+ "at": {
181
+ "type": "string"
182
+ },
183
+ "branch": {
184
+ "type": "string",
185
+ "pattern": "^[0-9]+/[0-9]+(?:/[a-z][a-z-]*)?$"
186
+ },
187
+ "event": {
188
+ "enum": [
189
+ "dispatched",
190
+ "waiting",
191
+ "resumed",
192
+ "done",
193
+ "blocked",
194
+ "invalid",
195
+ "resolved"
196
+ ]
197
+ },
198
+ "note": {
199
+ "type": "string"
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ }
@@ -11,6 +11,9 @@ How the entry uses them:
11
11
  2. If none matches, compose a chain from the operators' `## Next` tables and `routing.json`, under the
12
12
  same rules `scripts/validate-workflows.mjs` enforces on these files:
13
13
  - every branch names a real operator and presets only fields that operator declares;
14
+ - every Requirements field with no Default is either preset or listed under the branch's `asks`, so a
15
+ chain says up front which fields the entry must take from the mission scope or ask a person for
16
+ before that branch starts;
14
17
  - every required Input of a branch is produced by an earlier step;
15
18
  - branches of one step share no write alias (two operators may not write the same checkout or
16
19
  root at once; `frontend.surface.audit` fans out by matrix entry because it writes nothing);
@@ -11,6 +11,9 @@ Cửa vào dùng chúng như sau:
11
11
  2. Không khớp cái nào thì tự ghép chuỗi từ bảng `## Next` của các operator và `routing.json`, theo
12
12
  đúng luật mà `scripts/validate-workflows.mjs` ép lên các file này:
13
13
  - mỗi nhánh gọi tên một operator có thật và chỉ preset field mà operator đó khai;
14
+ - mọi field Requirements không có Default thì hoặc được preset, hoặc nằm trong `asks` của nhánh, để
15
+ chuỗi nói trước những field nào cửa vào phải lấy từ phạm vi nhiệm vụ hay hỏi người trước khi nhánh
16
+ đó chạy;
14
17
  - mọi Input bắt buộc của một nhánh phải do một bậc trước sinh ra;
15
18
  - các nhánh cùng bậc không chung alias ghi (hai operator không được cùng ghi một checkout hay một
16
19
  root; `frontend.surface.audit` toả theo entry của matrix vì nó không ghi gì);
@@ -19,7 +19,11 @@
19
19
  "operator": "business.decide",
20
20
  "requirements": {
21
21
  "mode": "model"
22
- }
22
+ },
23
+ "asks": [
24
+ "featureId",
25
+ "targetState"
26
+ ]
23
27
  }
24
28
  ],
25
29
  [
@@ -28,12 +32,21 @@
28
32
  "requirements": {
29
33
  "alternatives": 1,
30
34
  "selectionPolicy": "automatic"
31
- }
35
+ },
36
+ "asks": [
37
+ "objective",
38
+ "constraints"
39
+ ]
32
40
  }
33
41
  ],
34
42
  [
35
43
  {
36
- "operator": "backend.source.apply"
44
+ "operator": "backend.source.apply",
45
+ "asks": [
46
+ "featureId",
47
+ "outcome",
48
+ "mutableFileRefs"
49
+ ]
37
50
  }
38
51
  ],
39
52
  [
@@ -46,12 +59,20 @@
46
59
  "operator": "business.decide",
47
60
  "requirements": {
48
61
  "mode": "reconcile"
49
- }
62
+ },
63
+ "asks": [
64
+ "featureId",
65
+ "targetState"
66
+ ]
50
67
  }
51
68
  ],
52
69
  [
53
70
  {
54
- "operator": "git.publish"
71
+ "operator": "git.publish",
72
+ "asks": [
73
+ "boundary",
74
+ "approval"
75
+ ]
55
76
  }
56
77
  ]
57
78
  ],
@@ -11,7 +11,10 @@
11
11
  "operator": "content.generate",
12
12
  "requirements": {
13
13
  "maxReviewRounds": 2
14
- }
14
+ },
15
+ "asks": [
16
+ "unit"
17
+ ]
15
18
  }
16
19
  ]
17
20
  ],
@@ -16,8 +16,7 @@
16
16
  {
17
17
  "operator": "workspace.bind",
18
18
  "requirements": {
19
- "role": "fe",
20
- "runtimeNeed": "consume"
19
+ "role": "fe"
21
20
  }
22
21
  }
23
22
  ],
@@ -26,7 +25,11 @@
26
25
  "operator": "business.decide",
27
26
  "requirements": {
28
27
  "mode": "model"
29
- }
28
+ },
29
+ "asks": [
30
+ "featureId",
31
+ "targetState"
32
+ ]
30
33
  }
31
34
  ],
32
35
  [
@@ -35,7 +38,10 @@
35
38
  "requirements": {
36
39
  "intent": "create",
37
40
  "changeLevel": "new"
38
- }
41
+ },
42
+ "asks": [
43
+ "target"
44
+ ]
39
45
  }
40
46
  ],
41
47
  [
@@ -65,7 +71,11 @@
65
71
  ],
66
72
  [
67
73
  {
68
- "operator": "git.publish"
74
+ "operator": "git.publish",
75
+ "asks": [
76
+ "boundary",
77
+ "approval"
78
+ ]
69
79
  }
70
80
  ]
71
81
  ],
@@ -10,8 +10,7 @@
10
10
  {
11
11
  "operator": "workspace.bind",
12
12
  "requirements": {
13
- "role": "fe",
14
- "runtimeNeed": "consume"
13
+ "role": "fe"
15
14
  }
16
15
  }
17
16
  ],
@@ -21,7 +20,10 @@
21
20
  "requirements": {
22
21
  "intent": "modify",
23
22
  "changeLevel": "reconstruct"
24
- }
23
+ },
24
+ "asks": [
25
+ "target"
26
+ ]
25
27
  }
26
28
  ],
27
29
  [
@@ -51,7 +53,11 @@
51
53
  ],
52
54
  [
53
55
  {
54
- "operator": "git.publish"
56
+ "operator": "git.publish",
57
+ "asks": [
58
+ "boundary",
59
+ "approval"
60
+ ]
55
61
  }
56
62
  ]
57
63
  ],
@@ -10,8 +10,7 @@
10
10
  {
11
11
  "operator": "workspace.bind",
12
12
  "requirements": {
13
- "role": "fe",
14
- "runtimeNeed": "consume"
13
+ "role": "fe"
15
14
  }
16
15
  }
17
16
  ],
@@ -21,7 +20,10 @@
21
20
  "requirements": {
22
21
  "intent": "audit-repair",
23
22
  "changeLevel": "refine"
24
- }
23
+ },
24
+ "asks": [
25
+ "target"
26
+ ]
25
27
  }
26
28
  ],
27
29
  [
@@ -51,7 +53,11 @@
51
53
  ],
52
54
  [
53
55
  {
54
- "operator": "git.publish"
56
+ "operator": "git.publish",
57
+ "asks": [
58
+ "boundary",
59
+ "approval"
60
+ ]
55
61
  }
56
62
  ]
57
63
  ],