@starci/skills 1.1.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 (321) hide show
  1. package/INDEX.md +74 -0
  2. package/INDEX.vi.md +75 -0
  3. package/README.md +44 -0
  4. package/README.vi.md +43 -0
  5. package/SKILL.md +135 -0
  6. package/SKILL.vi.md +128 -0
  7. package/alias/INDEX.md +104 -0
  8. package/alias/INDEX.vi.md +104 -0
  9. package/alias/alias.json +297 -0
  10. package/bin/starci-skills.mjs +219 -0
  11. package/knowledge/INDEX.md +22 -0
  12. package/knowledge/INDEX.vi.md +22 -0
  13. package/knowledge/grammars/starci/DNA.md +146 -0
  14. package/knowledge/grammars/starci/DNA.vi.md +146 -0
  15. package/knowledge/grammars/starci/INDEX.md +25 -0
  16. package/knowledge/grammars/starci/INDEX.vi.md +25 -0
  17. package/knowledge/grammars/starci/family.md +50 -0
  18. package/knowledge/grammars/starci/family.vi.md +50 -0
  19. package/knowledge/grammars/starci/idioms.md +120 -0
  20. package/knowledge/grammars/starci/idioms.vi.md +121 -0
  21. package/knowledge/grammars/starci/playbook.md +36 -0
  22. package/knowledge/grammars/starci/playbook.vi.md +35 -0
  23. package/knowledge/patterns/be/INDEX.md +29 -0
  24. package/knowledge/patterns/be/INDEX.vi.md +29 -0
  25. package/knowledge/patterns/be/comment.md +80 -0
  26. package/knowledge/patterns/be/comment.vi.md +80 -0
  27. package/knowledge/patterns/be/error.md +86 -0
  28. package/knowledge/patterns/be/error.vi.md +86 -0
  29. package/knowledge/patterns/be/folder.md +87 -0
  30. package/knowledge/patterns/be/folder.vi.md +86 -0
  31. package/knowledge/patterns/be/function.md +80 -0
  32. package/knowledge/patterns/be/function.vi.md +80 -0
  33. package/knowledge/patterns/be/imports.md +79 -0
  34. package/knowledge/patterns/be/imports.vi.md +79 -0
  35. package/knowledge/patterns/be/naming.md +87 -0
  36. package/knowledge/patterns/be/naming.vi.md +87 -0
  37. package/knowledge/patterns/be/test.md +79 -0
  38. package/knowledge/patterns/be/test.vi.md +79 -0
  39. package/knowledge/patterns/be/typing.md +73 -0
  40. package/knowledge/patterns/be/typing.vi.md +73 -0
  41. package/knowledge/patterns/fe/INDEX.md +29 -0
  42. package/knowledge/patterns/fe/INDEX.vi.md +29 -0
  43. package/knowledge/patterns/fe/comment.md +70 -0
  44. package/knowledge/patterns/fe/comment.vi.md +70 -0
  45. package/knowledge/patterns/fe/error.md +61 -0
  46. package/knowledge/patterns/fe/error.vi.md +61 -0
  47. package/knowledge/patterns/fe/folder.md +98 -0
  48. package/knowledge/patterns/fe/folder.vi.md +95 -0
  49. package/knowledge/patterns/fe/function.md +70 -0
  50. package/knowledge/patterns/fe/function.vi.md +70 -0
  51. package/knowledge/patterns/fe/imports.md +87 -0
  52. package/knowledge/patterns/fe/imports.vi.md +87 -0
  53. package/knowledge/patterns/fe/naming.md +77 -0
  54. package/knowledge/patterns/fe/naming.vi.md +77 -0
  55. package/knowledge/patterns/fe/test.md +73 -0
  56. package/knowledge/patterns/fe/test.vi.md +73 -0
  57. package/knowledge/patterns/fe/typing.md +67 -0
  58. package/knowledge/patterns/fe/typing.vi.md +67 -0
  59. package/knowledge/ui/INDEX.md +101 -0
  60. package/knowledge/ui/INDEX.vi.md +101 -0
  61. package/knowledge/ui/composition/INDEX.md +60 -0
  62. package/knowledge/ui/composition/INDEX.vi.md +63 -0
  63. package/knowledge/ui/composition/accent.md +73 -0
  64. package/knowledge/ui/composition/accent.vi.md +74 -0
  65. package/knowledge/ui/composition/action.md +55 -0
  66. package/knowledge/ui/composition/action.vi.md +56 -0
  67. package/knowledge/ui/composition/coverage.md +37 -0
  68. package/knowledge/ui/composition/coverage.vi.md +37 -0
  69. package/knowledge/ui/composition/cta.md +79 -0
  70. package/knowledge/ui/composition/cta.vi.md +79 -0
  71. package/knowledge/ui/composition/feedback.md +55 -0
  72. package/knowledge/ui/composition/feedback.vi.md +56 -0
  73. package/knowledge/ui/composition/hierarchy.md +83 -0
  74. package/knowledge/ui/composition/hierarchy.vi.md +82 -0
  75. package/knowledge/ui/composition/layout.md +91 -0
  76. package/knowledge/ui/composition/layout.vi.md +93 -0
  77. package/knowledge/ui/composition/responsive.md +67 -0
  78. package/knowledge/ui/composition/responsive.vi.md +67 -0
  79. package/knowledge/ui/composition/state.md +105 -0
  80. package/knowledge/ui/composition/state.vi.md +106 -0
  81. package/knowledge/ui/presentation/INDEX.md +94 -0
  82. package/knowledge/ui/presentation/INDEX.vi.md +69 -0
  83. package/knowledge/ui/presentation/boundary.md +170 -0
  84. package/knowledge/ui/presentation/boundary.vi.md +169 -0
  85. package/knowledge/ui/presentation/font.md +155 -0
  86. package/knowledge/ui/presentation/font.vi.md +156 -0
  87. package/knowledge/ui/presentation/gap.md +181 -0
  88. package/knowledge/ui/presentation/gap.vi.md +181 -0
  89. package/knowledge/ui/presentation/margin.md +168 -0
  90. package/knowledge/ui/presentation/margin.vi.md +171 -0
  91. package/knowledge/ui/presentation/measure.md +174 -0
  92. package/knowledge/ui/presentation/measure.vi.md +178 -0
  93. package/knowledge/ui/presentation/overflow.md +142 -0
  94. package/knowledge/ui/presentation/overflow.vi.md +142 -0
  95. package/knowledge/ui/presentation/padding.md +293 -0
  96. package/knowledge/ui/presentation/padding.vi.md +292 -0
  97. package/knowledge/ui/presentation/surface.md +166 -0
  98. package/knowledge/ui/presentation/surface.vi.md +166 -0
  99. package/knowledge/ui/presentation/text-flow.md +123 -0
  100. package/knowledge/ui/presentation/text-flow.vi.md +123 -0
  101. package/knowledge/ui/presentation/tone.md +114 -0
  102. package/knowledge/ui/presentation/tone.vi.md +113 -0
  103. package/knowledge/ui/proof/INDEX.md +55 -0
  104. package/knowledge/ui/proof/INDEX.vi.md +55 -0
  105. package/knowledge/ui/proof/accessibility.md +67 -0
  106. package/knowledge/ui/proof/accessibility.vi.md +68 -0
  107. package/knowledge/ui/proof/contrast.md +58 -0
  108. package/knowledge/ui/proof/contrast.vi.md +57 -0
  109. package/knowledge/ui/proof/focus.md +76 -0
  110. package/knowledge/ui/proof/focus.vi.md +76 -0
  111. package/knowledge/ui/proof/motion.md +63 -0
  112. package/knowledge/ui/proof/motion.vi.md +64 -0
  113. package/knowledge/ui/proof/render-truth.md +63 -0
  114. package/knowledge/ui/proof/render-truth.vi.md +63 -0
  115. package/operators/INDEX.md +199 -0
  116. package/operators/INDEX.vi.md +199 -0
  117. package/operators/architecture-decide/errors.json +115 -0
  118. package/operators/architecture-decide/operator.json +20 -0
  119. package/operators/architecture-decide/operator.md +133 -0
  120. package/operators/architecture-decide/operator.vi.md +130 -0
  121. package/operators/architecture-decide/self-test.mjs +221 -0
  122. package/operators/architecture-decide/validate.mjs +112 -0
  123. package/operators/backend-source-apply/errors.json +66 -0
  124. package/operators/backend-source-apply/operator.json +20 -0
  125. package/operators/backend-source-apply/operator.md +189 -0
  126. package/operators/backend-source-apply/operator.vi.md +185 -0
  127. package/operators/backend-source-apply/self-test.mjs +257 -0
  128. package/operators/backend-source-apply/validate.mjs +240 -0
  129. package/operators/business-decide/errors.json +78 -0
  130. package/operators/business-decide/operator.json +20 -0
  131. package/operators/business-decide/operator.md +176 -0
  132. package/operators/business-decide/operator.vi.md +174 -0
  133. package/operators/business-decide/self-test.mjs +225 -0
  134. package/operators/business-decide/validate.mjs +277 -0
  135. package/operators/content-generate/errors.json +106 -0
  136. package/operators/content-generate/operator.json +21 -0
  137. package/operators/content-generate/operator.md +155 -0
  138. package/operators/content-generate/operator.vi.md +155 -0
  139. package/operators/content-generate/self-test.mjs +288 -0
  140. package/operators/content-generate/validate.mjs +196 -0
  141. package/operators/errors.json +178 -0
  142. package/operators/frontend-direction-decide/errors.json +135 -0
  143. package/operators/frontend-direction-decide/operator.json +21 -0
  144. package/operators/frontend-direction-decide/operator.md +167 -0
  145. package/operators/frontend-direction-decide/operator.vi.md +167 -0
  146. package/operators/frontend-direction-decide/self-test.mjs +226 -0
  147. package/operators/frontend-direction-decide/validate.mjs +146 -0
  148. package/operators/frontend-presentation-resolve/errors.json +42 -0
  149. package/operators/frontend-presentation-resolve/operator.json +19 -0
  150. package/operators/frontend-presentation-resolve/operator.md +142 -0
  151. package/operators/frontend-presentation-resolve/operator.vi.md +140 -0
  152. package/operators/frontend-presentation-resolve/self-test.mjs +163 -0
  153. package/operators/frontend-presentation-resolve/validate.mjs +143 -0
  154. package/operators/frontend-source-apply/errors.json +30 -0
  155. package/operators/frontend-source-apply/operator.json +20 -0
  156. package/operators/frontend-source-apply/operator.md +127 -0
  157. package/operators/frontend-source-apply/operator.vi.md +126 -0
  158. package/operators/frontend-source-apply/self-test.mjs +214 -0
  159. package/operators/frontend-source-apply/validate.mjs +133 -0
  160. package/operators/frontend-surface-audit/errors.json +5 -0
  161. package/operators/frontend-surface-audit/operator.json +22 -0
  162. package/operators/frontend-surface-audit/operator.md +121 -0
  163. package/operators/frontend-surface-audit/operator.vi.md +121 -0
  164. package/operators/frontend-surface-audit/self-test.mjs +185 -0
  165. package/operators/frontend-surface-audit/validate.mjs +127 -0
  166. package/operators/git-publish/errors.json +54 -0
  167. package/operators/git-publish/operator.json +20 -0
  168. package/operators/git-publish/operator.md +180 -0
  169. package/operators/git-publish/operator.vi.md +178 -0
  170. package/operators/git-publish/self-test.mjs +177 -0
  171. package/operators/git-publish/validate.mjs +106 -0
  172. package/operators/platform-operate/errors.json +90 -0
  173. package/operators/platform-operate/operator.json +22 -0
  174. package/operators/platform-operate/operator.md +162 -0
  175. package/operators/platform-operate/operator.vi.md +160 -0
  176. package/operators/platform-operate/self-test.mjs +202 -0
  177. package/operators/platform-operate/validate.mjs +193 -0
  178. package/operators/quality-verify/errors.json +54 -0
  179. package/operators/quality-verify/operator.json +20 -0
  180. package/operators/quality-verify/operator.md +185 -0
  181. package/operators/quality-verify/operator.vi.md +177 -0
  182. package/operators/quality-verify/self-test.mjs +210 -0
  183. package/operators/quality-verify/validate.mjs +197 -0
  184. package/operators/release-deploy/errors.json +158 -0
  185. package/operators/release-deploy/operator.json +23 -0
  186. package/operators/release-deploy/operator.md +183 -0
  187. package/operators/release-deploy/operator.vi.md +181 -0
  188. package/operators/release-deploy/self-test.mjs +235 -0
  189. package/operators/release-deploy/validate.mjs +129 -0
  190. package/operators/uat-verify/errors.json +78 -0
  191. package/operators/uat-verify/operator.json +25 -0
  192. package/operators/uat-verify/operator.md +162 -0
  193. package/operators/uat-verify/operator.vi.md +161 -0
  194. package/operators/uat-verify/self-test.mjs +270 -0
  195. package/operators/uat-verify/validate.mjs +202 -0
  196. package/operators/workspace-bind/errors.json +90 -0
  197. package/operators/workspace-bind/operator.json +21 -0
  198. package/operators/workspace-bind/operator.md +148 -0
  199. package/operators/workspace-bind/operator.vi.md +148 -0
  200. package/operators/workspace-bind/self-test.mjs +205 -0
  201. package/operators/workspace-bind/validate.mjs +152 -0
  202. package/package.json +50 -0
  203. package/readiness/initialization/workspaces/commit-policy.json +91 -0
  204. package/readiness/initialization/workspaces/config.schema.json +35 -0
  205. package/readiness/initialization/workspaces/device-state.schema.json +54 -0
  206. package/readiness/initialization/workspaces/local-route.schema.json +206 -0
  207. package/readiness/initialization/workspaces/portable-route.schema.json +200 -0
  208. package/resources/INDEX.md +96 -0
  209. package/resources/INDEX.vi.md +99 -0
  210. package/resources/agents/profiles/claude.json +131 -0
  211. package/resources/agents/profiles/openai.json +131 -0
  212. package/resources/orchestrator.json +71 -0
  213. package/resources/tools.json +85 -0
  214. package/routing.json +272 -0
  215. package/scripts/alias-registry.mjs +31 -0
  216. package/scripts/device-state.mjs +497 -0
  217. package/scripts/device-state.spec.mjs +18 -0
  218. package/scripts/errors-registry.mjs +68 -0
  219. package/scripts/generate-alias-doc.mjs +66 -0
  220. package/scripts/generate-grammar-dna.mjs +387 -0
  221. package/scripts/generate-operators-index.mjs +95 -0
  222. package/scripts/generate-presentation-owned.mjs +681 -0
  223. package/scripts/install-cli.spec.mjs +74 -0
  224. package/scripts/json-schema.mjs +94 -0
  225. package/scripts/operator-md.mjs +96 -0
  226. package/scripts/run-operator-self-tests.mjs +36 -0
  227. package/scripts/validate-alias.mjs +165 -0
  228. package/scripts/validate-defaults.mjs +72 -0
  229. package/scripts/validate-knowledge-citations.mjs +90 -0
  230. package/scripts/validate-operator.mjs +125 -0
  231. package/scripts/validate-request.mjs +80 -0
  232. package/scripts/validate-resources.mjs +117 -0
  233. package/scripts/validate-response.mjs +141 -0
  234. package/scripts/validate-routing.mjs +91 -0
  235. package/scripts/validate-step.mjs +50 -0
  236. package/scripts/validate-templates.mjs +226 -0
  237. package/scripts/validate-templates.spec.mjs +144 -0
  238. package/scripts/validate-workflows.mjs +106 -0
  239. package/scripts/workspace-portable.mjs +389 -0
  240. package/scripts/workspace-portable.spec.mjs +246 -0
  241. package/templates/README.md +47 -0
  242. package/templates/README.vi.md +45 -0
  243. package/templates/changes.example.md +27 -0
  244. package/templates/grammars.template.md +34 -0
  245. package/templates/kinds/architecture-decision.contract.json +14 -0
  246. package/templates/kinds/architecture-decision.skeleton.md +52 -0
  247. package/templates/kinds/backend-source-application.contract.json +10 -0
  248. package/templates/kinds/backend-source-application.skeleton.md +34 -0
  249. package/templates/kinds/business-promise-authority.contract.json +13 -0
  250. package/templates/kinds/business-promise-authority.skeleton.md +67 -0
  251. package/templates/kinds/capture.schema.json +33 -0
  252. package/templates/kinds/changes.contract.json +10 -0
  253. package/templates/kinds/changes.skeleton.md +26 -0
  254. package/templates/kinds/checks.schema.json +44 -0
  255. package/templates/kinds/claims.schema.json +165 -0
  256. package/templates/kinds/conformance.schema.json +15 -0
  257. package/templates/kinds/content-brief.contract.json +12 -0
  258. package/templates/kinds/content-brief.skeleton.md +45 -0
  259. package/templates/kinds/content-generation-receipt.contract.json +11 -0
  260. package/templates/kinds/content-generation-receipt.skeleton.md +40 -0
  261. package/templates/kinds/content-review.contract.json +11 -0
  262. package/templates/kinds/content-review.skeleton.md +45 -0
  263. package/templates/kinds/contract.schema.json +28 -0
  264. package/templates/kinds/coverage-matrix.schema.json +86 -0
  265. package/templates/kinds/coverage.schema.json +62 -0
  266. package/templates/kinds/current-state.schema.json +40 -0
  267. package/templates/kinds/delta.schema.json +95 -0
  268. package/templates/kinds/e2e.schema.json +63 -0
  269. package/templates/kinds/frontend-direction-decision.contract.json +93 -0
  270. package/templates/kinds/frontend-direction-decision.skeleton.md +68 -0
  271. package/templates/kinds/frontend-presentation-resolution.contract.json +11 -0
  272. package/templates/kinds/frontend-presentation-resolution.skeleton.md +32 -0
  273. package/templates/kinds/frontend-source-application.contract.json +10 -0
  274. package/templates/kinds/frontend-source-application.skeleton.md +30 -0
  275. package/templates/kinds/frontend-surface-audit.contract.json +52 -0
  276. package/templates/kinds/frontend-surface-audit.skeleton.md +32 -0
  277. package/templates/kinds/gate-result.schema.json +64 -0
  278. package/templates/kinds/git-publication.contract.json +82 -0
  279. package/templates/kinds/git-publication.skeleton.md +61 -0
  280. package/templates/kinds/independent-critique.contract.json +9 -0
  281. package/templates/kinds/independent-critique.skeleton.md +28 -0
  282. package/templates/kinds/inventory.schema.json +35 -0
  283. package/templates/kinds/model.schema.json +99 -0
  284. package/templates/kinds/mutations.schema.json +65 -0
  285. package/templates/kinds/platform-operation-receipt.contract.json +76 -0
  286. package/templates/kinds/platform-operation-receipt.skeleton.md +54 -0
  287. package/templates/kinds/probes.schema.json +130 -0
  288. package/templates/kinds/proof.schema.json +17 -0
  289. package/templates/kinds/quality-verification.contract.json +87 -0
  290. package/templates/kinds/quality-verification.skeleton.md +58 -0
  291. package/templates/kinds/release-deployment.contract.json +85 -0
  292. package/templates/kinds/release-deployment.skeleton.md +67 -0
  293. package/templates/kinds/route.schema.json +293 -0
  294. package/templates/kinds/stack-model.schema.json +90 -0
  295. package/templates/kinds/uat-capture.schema.json +35 -0
  296. package/templates/kinds/uat-flow-verification.contract.json +11 -0
  297. package/templates/kinds/uat-flow-verification.skeleton.md +47 -0
  298. package/templates/kinds/uat-snapshot.schema.json +96 -0
  299. package/templates/kinds/uat-verdicts.schema.json +41 -0
  300. package/templates/kinds/ui-coverage.schema.json +77 -0
  301. package/templates/kinds/verdicts.schema.json +39 -0
  302. package/templates/kinds/workspace-route-binding.contract.json +12 -0
  303. package/templates/kinds/workspace-route-binding.skeleton.md +60 -0
  304. package/templates/kinds/writes.schema.json +37 -0
  305. package/templates/operator.template.md +73 -0
  306. package/templates/patterns.template.md +31 -0
  307. package/templates/step/request.schema.json +42 -0
  308. package/templates/step/response.schema.json +144 -0
  309. package/templates/ui-composition.template.md +36 -0
  310. package/templates/ui-presentation.template.md +57 -0
  311. package/templates/ui-proof.template.md +34 -0
  312. package/workflows/README.md +37 -0
  313. package/workflows/README.vi.md +37 -0
  314. package/workflows/backend-feature.json +59 -0
  315. package/workflows/content-unit.json +19 -0
  316. package/workflows/frontend-new-surface.json +81 -0
  317. package/workflows/frontend-reconstruct.json +67 -0
  318. package/workflows/frontend-refine.json +67 -0
  319. package/workflows/frontend-with-uat.json +78 -0
  320. package/workflows/full-feature.json +104 -0
  321. package/workflows/release.json +29 -0
package/INDEX.md ADDED
@@ -0,0 +1,74 @@
1
+ # StarCi Skills 1.1.0
2
+
3
+ This tree is the runtime. Read [SKILL.md](SKILL.md) next; it is the single entry that freezes a
4
+ mission's scope, selects the one operator that owns the outcome, and routes between operators on
5
+ typed results.
6
+
7
+ ## Load order
8
+
9
+ 1. `SKILL.md` — entry, routing loop, and the authority statement.
10
+ 2. `routing.json` — the closed map from every domain a stop code hands to (see the Stop codes table of
11
+ `operators/INDEX.md`) to its next step. It is validated against the operators' Stops tables, so a
12
+ missing route is a build failure. `workflows/` holds the example chains the entry reuses.
13
+ 3. `resources/` — which execution profile runs each operator role, which runtime grants it may use,
14
+ and its standing answers on web search, Grammar binding, and image generation. Also validated.
15
+ 4. The one operator the mission needs: its `operator.md` (Job, Context, Inputs, Requirements, Steps,
16
+ Outputs, Stops, Next) plus `operator.json` (id, domain, resources). Stop codes resolve through the
17
+ Stop codes table of `operators/INDEX.md`.
18
+ 5. Only the knowledge topics that operator binds.
19
+
20
+ Do not preload the tree. An operator binds the smallest set of topics its decision needs, each with
21
+ its fingerprint and complete rule inventory, and may emit no identifier outside that inventory.
22
+
23
+ ## Layout
24
+
25
+ ```text
26
+ SKILL.md one entry, fourteen operators, one routing map
27
+ routing.json 14 operators, 68 routes, four kinds: operator | resume | user | external
28
+ alias/ alias.json (machine registry: location, scheme, binding, writers, zone) + INDEX.md (generated map by zone); every operator reads by alias only
29
+ resources/ tools.json (the closed tool registry: modes and per-runtime support, addressed as @tools/<id>) + agents/profiles/{openai,claude}.json (6 profiles, permits per tool) + orchestrator.json (one agent per operator, max 3, profile equivalents); validated
30
+ workflows/ example chains (steps of parallel branches, loops, presets) the entry reuses when a request matches their when; otherwise it composes its own under the same rules; validated
31
+ operators/INDEX.md generated: what each operator reads, which kinds it consumes and produces, its steps, and every stop code with its disposition; operators/errors.json holds the codes several operators share
32
+ operators/<id>/ operator.md (+vi) one authored file per operator, operator.json (id, domain, resources), errors.json (its own codes), validate.mjs, self-test.mjs
33
+ knowledge/
34
+ ui/composition/ what a tree must contain, before it exists -> frontend.direction.decide
35
+ ui/presentation/ which CSS value an app-owned boundary takes -> frontend.presentation.resolve
36
+ ui/proof/ what is only true once rendered -> frontend.surface.audit
37
+ patterns/fe, be code conventions extracted from the two live sources
38
+ grammars/<family>/ one visual family's realization of Common
39
+ templates/ one template per document kind; each carries the json template-contract the tree is checked against;
40
+ kinds/ types every file that crosses between steps (<kind>.contract.json + <kind>.skeleton.md for markdown, <kind>.schema.json for data); step/ holds the request.json and response.json gates
41
+ scripts/ validate-routing.mjs, validate-resources.mjs, validate-knowledge-citations.mjs, validate-alias.mjs, validate-templates.mjs, validate-operator.mjs, validate-workflows.mjs, validate-request.mjs, validate-response.mjs, validate-step.mjs, run-operator-self-tests.mjs;
42
+ device-state.mjs and workspace-portable.mjs (+ specs), which the backend package.json calls
43
+ readiness/ workspaces/ schemas that the portable and hydrated route declarations name as $schema
44
+ ```
45
+
46
+ `npm test` runs the routing validation, the resources validation, the knowledge citation check, the template check, every operator self-test, and the script specs. It is green at the published
47
+ head or the head is not publishable.
48
+
49
+ ## Rules that hold everywhere
50
+
51
+ - An operator performs one job in one linear pass. It never calls another operator, routes a
52
+ workflow, pauses internally, or returns free-form control instructions. The parent alone maps a
53
+ validated output to the next transition.
54
+ - Only a validated field routes. Prose in a receipt, a narrated outcome, or an output that failed its
55
+ validator does not route.
56
+ - Authority lives in operator schemas, not in this file or in `SKILL.md`. `git.publish` cannot
57
+ express a force push; `release.deploy` cannot run without its declared authorization;
58
+ `uat.verify` has no field that can hold a credential.
59
+ - English `.md` files are the only runtime authority. Same-stem `.vi.md` files are human mirrors and
60
+ never enter a context manifest, dependency list, validator input, or operator binding.
61
+ - Rule IDs are stable public addresses. Append; never renumber, reuse, or silently change meaning.
62
+
63
+ ## Lineage
64
+
65
+ 1.1.0 (2026-09-03): the tree ships as the npm package @starci/skills; npx @starci/skills init installs it as a repository's .claude runtime with the CLAUDE.md and AGENTS.md bootstraps, update keeps local edits, doctor runs the validators on the installed copy; @starci/grammar 0.4.2 (the core entry re-exports Common).
66
+
67
+ 1.0.3 (2026-09-03): a tools registry replaces grants and policies (resources/tools.json, @tools/<id> in Steps, per-runtime support, profile equivalents); every operator binds an OpenAI profile for the Codex processor; the first test round (tests/) and its fixes; docs/ and sites/ return.
68
+
69
+ 1.0.2 (2026-09-03): every operator is one authored operator.md with a request/response branch layout, JSON kind contracts, an errors registry with dispositions, example workflows, and the frontend.*/backend.source.apply names; 1.0.1 was the dry-run round that exposed the old shape.
70
+
71
+
72
+ This tree replaced the v7.6 runtime on 2026-09-02. The complete v7.6 tree, including its 13 skills,
73
+ 113 operators, templates, and runtime contracts, is preserved on the `v7` branch of this repository.
74
+ A v8 document that cites a v7-only file names that branch.
package/INDEX.vi.md ADDED
@@ -0,0 +1,75 @@
1
+ # StarCi Skills 1.1.0
2
+
3
+ Cây này chính là runtime. Đọc tiếp `SKILL.vi.md` nếu có, hoặc `SKILL.md`; đó là cửa vào duy nhất,
4
+ đóng băng phạm vi của một nhiệm vụ, chọn đúng một operator sở hữu kết quả, rồi định tuyến giữa các
5
+ operator dựa trên kết quả có kiểu.
6
+
7
+ ## Thứ tự nạp
8
+
9
+ 1. `SKILL.md`: cửa vào, vòng lặp định tuyến, và tuyên bố về thẩm quyền.
10
+ 2. `routing.json`: bảng đóng ánh xạ mọi domain mà mã dừng bàn giao tới (xem bảng Mã dừng trong
11
+ `operators/INDEX.md`) sang bước kế tiếp. Bảng được kiểm đối chiếu với bảng Dừng của các operator,
12
+ nên thiếu một route là lỗi build. `workflows/` giữ các chuỗi mẫu mà cửa vào dùng lại.
13
+ 3. `resources/`: profile thực thi nào chạy từng vai trò của operator, nó được dùng quyền nào lúc
14
+ chạy, và câu trả lời thường trực về tìm mạng, ràng Grammar, sinh hình. Cũng được kiểm.
15
+ 4. Đúng một operator mà nhiệm vụ cần: `operator.md` (Việc, Context, Đầu vào, Yêu cầu, Các bước, Đầu ra,
16
+ Dừng, Kế tiếp) cùng `operator.json` (id, domain, resources). Mã dừng tra ở bảng Mã dừng trong `operators/INDEX.md`.
17
+ 5. Chỉ những topic knowledge mà operator đó bind.
18
+
19
+ Không nạp trước cả cây. Một operator bind tập topic nhỏ nhất mà quyết định của nó cần, mỗi topic kèm
20
+ fingerprint và danh sách rule đầy đủ, và không được phát ra mã nào ngoài danh sách ấy.
21
+
22
+ ## Bố cục
23
+
24
+ ```text
25
+ SKILL.md một cửa vào, mười bốn operator, một bảng định tuyến
26
+ routing.json 14 operator, 68 route, bốn loại: operator | resume | user | external
27
+ alias/ alias.json (sổ cho máy: vị trí, scheme, bind, ai ghi, vùng) + INDEX.md (bản đồ sinh theo vùng); operator chỉ đọc qua alias
28
+ resources/ tools.json (sổ tool đóng: mode và hỗ trợ theo runtime, gọi bằng @tools/<id>) + agents/profiles/{openai,claude}.json (6 profile, quyền theo tool) + orchestrator.json (mỗi operator một agent, tối đa 3, profile tương đương); có kiểm
29
+ workflows/ chuỗi mẫu (các bậc gồm nhánh song song, vòng lặp, preset) mà cửa vào dùng lại khi request khớp when; không khớp thì tự ghép theo cùng luật; có kiểm
30
+ operators/INDEX.md sinh tự động: mỗi operator đọc gì, tiêu thụ và sinh kind nào, số bước, và mọi mã dừng kèm cách xử lý; operators/errors.json giữ mã dùng chung
31
+ operators/<id>/ operator.md (+vi) một file viết tay cho mỗi operator, operator.json (id, domain, resources), errors.json (mã riêng), validate.mjs, self-test.mjs
32
+ knowledge/
33
+ ui/composition/ cây phải chứa gì, trước khi nó tồn tại -> frontend.direction.decide
34
+ ui/presentation/ ranh giới do app sở hữu lấy giá trị CSS nào -> frontend.presentation.resolve
35
+ ui/proof/ thứ chỉ đúng sai sau khi đã render -> frontend.surface.audit
36
+ patterns/fe, be quy ước code trích từ hai source thật
37
+ grammars/<họ>/ cách một họ hình ảnh hiện thực Common
38
+ templates/ mỗi loại tài liệu một template; mỗi template mang khối json template-contract dùng để kiểm cả cây;
39
+ kinds/ định kiểu mọi file đi qua giữa các bước (<kind>.contract.json + <kind>.skeleton.md cho markdown, <kind>.schema.json cho dữ liệu); step/ giữ hai gate request.json và response.json
40
+ scripts/ validate-routing.mjs, validate-resources.mjs, validate-knowledge-citations.mjs, validate-alias.mjs, validate-templates.mjs, validate-operator.mjs, validate-workflows.mjs, validate-request.mjs, validate-response.mjs, validate-step.mjs, run-operator-self-tests.mjs;
41
+ device-state.mjs và workspace-portable.mjs (+ spec), thứ package.json của backend gọi tới
42
+ readiness/ các schema workspaces/ mà khai báo route portable và hydrate gọi tên trong $schema
43
+ ```
44
+
45
+ `npm test` chạy kiểm định tuyến, kiểm resources, kiểm trích dẫn knowledge, kiểm template, mọi self-test của operator, và các spec của script. Head đã publish phải xanh, không xanh
46
+ thì không được publish.
47
+
48
+ ## Luật áp dụng khắp nơi
49
+
50
+ - Một operator làm đúng một việc trong một lượt tuyến tính. Nó không gọi operator khác, không điều
51
+ phối workflow, không tự dừng giữa chừng, không trả chỉ dẫn điều khiển dạng văn xuôi. Chỉ cha mới
52
+ ánh xạ một output đã validate sang bước chuyển kế tiếp.
53
+ - Chỉ trường đã validate mới định tuyến được. Văn xuôi trong receipt, kết quả kể bằng lời, hay
54
+ output trượt validator đều không định tuyến.
55
+ - Thẩm quyền nằm trong schema của operator, không nằm ở file này hay ở `SKILL.md`. `git.publish`
56
+ không diễn đạt được force push; `release.deploy` không chạy nổi khi thiếu authorization đã khai;
57
+ `uat.verify` không có trường nào chứa nổi credential.
58
+ - File `.md` tiếng Anh là authority duy nhất lúc chạy. File `.vi.md` cùng tên là bản đọc cho người,
59
+ không bao giờ vào context manifest, danh sách phụ thuộc, input của validator, hay binding của
60
+ operator.
61
+ - Mã rule là địa chỉ công khai ổn định. Chỉ thêm; không đánh số lại, không dùng lại, không lặng lẽ
62
+ đổi nghĩa.
63
+
64
+ ## Dòng dõi
65
+
66
+ 1.1.0 (2026-09-03): cây phát hành thành gói npm @starci/skills; npx @starci/skills init cài nó làm runtime .claude của một repository kèm bootstrap CLAUDE.md và AGENTS.md, update giữ sửa đổi tay, doctor chạy validator trên bản đã cài; @starci/grammar 0.4.2 (entry core re-export Common).
67
+
68
+ 1.0.3 (2026-09-03): sổ tool thay cho grant và policy (resources/tools.json, @tools/<id> trong Các bước, hỗ trợ theo runtime, profile tương đương); mọi operator ràng profile OpenAI cho processor Codex; vòng test đầu (tests/) và các sửa từ đó; docs/ và sites/ trở lại.
69
+
70
+ 1.0.2 (2026-09-03): mọi operator là một operator.md viết tay với layout nhánh request/response, hợp đồng kind JSON, sổ mã dừng có cách xử lý, workflow mẫu, và tên frontend.* / backend.source.apply; 1.0.1 là vòng chạy khô đã lộ ra dạng cũ.
71
+
72
+
73
+ Cây này thay thế runtime v7.6 vào ngày 2026-09-02. Toàn bộ cây v7.6, gồm 13 skill, 113 operator,
74
+ template và các contract runtime, được giữ nguyên trên nhánh `v7` của cùng repository. Tài liệu v8
75
+ nào dẫn tới một file chỉ có ở v7 thì gọi tên nhánh đó.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @starci/skills
2
+
3
+ StarCi Skills is the `.claude` runtime of a repository: one entry (`SKILL.md`), fourteen operators,
4
+ eight example workflows, one closed routing map and one tool registry. An agent in Claude Code or
5
+ Codex reads `.claude/INDEX.md` through a one-paragraph bootstrap and follows its load order; the tree
6
+ does the rest. Documentation: <https://harness.starci.org/docs/>. Tiếng Việt: [README.vi.md](README.vi.md).
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npx @starci/skills init
12
+ ```
13
+
14
+ Run it at the root of the repository that will own the runtime. It copies the tree into `./.claude`,
15
+ writes `CLAUDE.md` (read by Claude Code) and `AGENTS.md` (read by Codex) when they do not exist, and
16
+ adds `.worktrees/sessions/` to `.gitignore`, where sessions live. Commit `.claude/` with the repository:
17
+ it is source, not a cache. Requires Node 20 or newer; the CLI has no dependencies.
18
+
19
+ | Command | What it does |
20
+ | --- | --- |
21
+ | `npx @starci/skills init [--dir <repo>] [--force] [--no-bootstrap]` | Installs the tree and the bootstraps. Refuses a populated `.claude` it did not install unless `--force`, and even then replaces only the runtime paths. |
22
+ | `npx @starci/skills update [--dir <repo>] [--force]` | Brings an installed tree to this package's version. A file changed locally is kept and listed; `--force` takes the package version. Files outside the runtime paths are never touched. |
23
+ | `npx @starci/skills doctor [--dir <repo>] [--quick]` | Runs the tree's own validators on the installed copy (routing, alias, operators, workflows, defaults, templates, knowledge citations, the operator self-tests and the script specs) and reports files changed since install. |
24
+ | `npx @starci/skills version` | Prints the package version. |
25
+
26
+ The runtime paths are `INDEX.md`, `INDEX.vi.md`, `SKILL.md`, `SKILL.vi.md`, `routing.json`, `alias/`,
27
+ `knowledge/`, `operators/`, `readiness/`, `resources/`, `scripts/`, `templates/`, `workflows/`. The
28
+ manifest `.claude/.starci-skills.json` records the installed version and a hash per file; `update` and
29
+ `doctor` read it.
30
+
31
+ ## Claude Code and Codex
32
+
33
+ Both runtimes are entered the same way. `CLAUDE.md` and `AGENTS.md` carry the same bootstrap: read
34
+ `.claude/INDEX.md` completely and follow its load order. The processor runs each operator on the profile
35
+ its `operator.json` binds (`resources/agents/profiles/openai.json` for Codex, `claude.json` for Claude
36
+ Code, paired in `resources/orchestrator.json`), and each operator may call only the tools its
37
+ `operator.json` declares from `resources/tools.json`. The English files are the runtime authority; the
38
+ `.vi.md` siblings are for people.
39
+
40
+ ## Develop
41
+
42
+ This repository is the package. `npm test` runs every validator, the operator self-tests, the script
43
+ specs and the docs check; `docs/` is the Nextra site and `sites/skills` the landing, neither ships in
44
+ the package.
package/README.vi.md ADDED
@@ -0,0 +1,43 @@
1
+ # @starci/skills
2
+
3
+ StarCi Skills là runtime `.claude` của một repository: một cửa vào (`SKILL.md`), mười bốn operator, tám
4
+ workflow ví dụ, một bản đồ routing đóng và một sổ tool. Agent trong Claude Code hay Codex đọc
5
+ `.claude/INDEX.md` qua một đoạn bootstrap ngắn rồi theo đúng thứ tự nạp của nó; phần còn lại là việc của
6
+ cây. Tài liệu: <https://harness.starci.org/docs/vi>. Bản tiếng Anh là thẩm quyền khi chạy: [README.md](README.md).
7
+
8
+ ## Cài đặt
9
+
10
+ ```bash
11
+ npx @starci/skills init
12
+ ```
13
+
14
+ Chạy ở gốc repository sẽ sở hữu runtime. Lệnh chép cây vào `./.claude`, viết `CLAUDE.md` (Claude Code
15
+ đọc) và `AGENTS.md` (Codex đọc) khi chưa có, và thêm `.worktrees/sessions/` vào `.gitignore` vì phiên
16
+ làm việc nằm ở đó. Hãy commit `.claude/` cùng repository: nó là source, không phải cache. Cần Node 20
17
+ trở lên; CLI không có dependency.
18
+
19
+ | Lệnh | Việc nó làm |
20
+ | --- | --- |
21
+ | `npx @starci/skills init [--dir <repo>] [--force] [--no-bootstrap]` | Cài cây và hai bootstrap. Từ chối một `.claude` đã có sẵn mà không do nó cài, trừ khi `--force`, và kể cả khi đó cũng chỉ thay các đường dẫn runtime. |
22
+ | `npx @starci/skills update [--dir <repo>] [--force]` | Nâng cây đã cài lên phiên bản của gói. File đã sửa tay được giữ lại và liệt kê; `--force` lấy bản của gói. File ngoài các đường dẫn runtime không bao giờ bị đụng. |
23
+ | `npx @starci/skills doctor [--dir <repo>] [--quick]` | Chạy chính bộ validator của cây trên bản đã cài (routing, alias, operator, workflow, mặc định, template, trích dẫn knowledge, self-test của operator và spec của script) và báo những file đã đổi từ lúc cài. |
24
+ | `npx @starci/skills version` | In phiên bản gói. |
25
+
26
+ Các đường dẫn runtime là `INDEX.md`, `INDEX.vi.md`, `SKILL.md`, `SKILL.vi.md`, `routing.json`,
27
+ `alias/`, `knowledge/`, `operators/`, `readiness/`, `resources/`, `scripts/`, `templates/`,
28
+ `workflows/`. Manifest `.claude/.starci-skills.json` ghi phiên bản đã cài và hash từng file; `update` và
29
+ `doctor` đọc nó.
30
+
31
+ ## Claude Code và Codex
32
+
33
+ Hai runtime vào cùng một cửa. `CLAUDE.md` và `AGENTS.md` mang cùng một đoạn bootstrap: đọc trọn
34
+ `.claude/INDEX.md` và theo thứ tự nạp của nó. Processor chạy từng operator trên profile mà
35
+ `operator.json` của nó ràng (`resources/agents/profiles/openai.json` cho Codex, `claude.json` cho Claude
36
+ Code, ghép cặp trong `resources/orchestrator.json`), và mỗi operator chỉ được gọi những tool mà
37
+ `operator.json` của nó khai từ `resources/tools.json`. File tiếng Anh là thẩm quyền khi chạy; bản `.vi.md`
38
+ dành cho người đọc.
39
+
40
+ ## Phát triển
41
+
42
+ Repository này chính là gói. `npm test` chạy mọi validator, self-test của operator, spec của script và
43
+ kiểm tra docs; `docs/` là site Nextra và `sites/skills` là landing, cả hai không nằm trong gói.
package/SKILL.md ADDED
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: starci
3
+ description: Complete one StarCi mission by freezing its scope, selecting the one operator that owns the outcome, and routing between operators on typed results until the outcome is proved or a person must decide.
4
+ ---
5
+
6
+ # StarCi
7
+
8
+ One entry, fourteen operators, eight example workflows, one closed routing map, one tool registry. This file picks the
9
+ workflow or composes one, selects the first operator, and sequences the rest. It does no work of its own: it never decides a value, writes source, or judges a
10
+ result.
11
+
12
+ ## Setup
13
+
14
+ 1. Freeze one mission scope: the unit, the target, inclusions and exclusions, write roots, external
15
+ effects, and what will count as proof. Two readings that would change any of those is one focused
16
+ question, not a guess.
17
+ 2. Run `workspace.bind` for any mission that reads or writes routed source. Nothing else may resolve a
18
+ checkout, and a similar directory name is never route authority.
19
+ 3. Look for a workflow first: read the `when` of every example in `workflows/`. A match is run as
20
+ written, its presets filling `request.json`. No match means composing a chain from the operators'
21
+ `## Next` tables under the rules `workflows/README.md` states (required inputs produced earlier,
22
+ no shared write alias inside a step, loops capped, a declared end); a composed chain worth keeping
23
+ becomes a new example.
24
+ 4. Select the first operator of that chain. Read only that operator's `operator.md` and
25
+ `operator.json`.
26
+ 5. Run that operator, end to end, on the one profile its `operator.json` names under `resources`, with
27
+ only the grants it lists. An operator has no other model, no inherited turns, and no grant the
28
+ assignment omits.
29
+
30
+ ## Entry
31
+
32
+ | The request is about | First operator |
33
+ | --- | --- |
34
+ | Which project, checkout, or runtime binding applies | `workspace.bind` |
35
+ | What the product promises, who may have it, what happens when it fails | `business.decide` |
36
+ | System boundaries, data ownership, or the tech stack | `architecture.decide` |
37
+ | Server behaviour, an API contract, persistence, or a job | `backend.source.apply` |
38
+ | Creating, restructuring, or redesigning a page or surface | `frontend.direction.decide` |
39
+ | Which CSS value an already-composed tree takes | `frontend.presentation.resolve` |
40
+ | Writing an already-resolved tree into product source | `frontend.source.apply` |
41
+ | Whether a rendered surface actually holds up | `frontend.surface.audit` |
42
+ | Build, lint, typecheck, coverage, or Sonar | `quality.verify` |
43
+ | Whether a real person can complete a real journey | `uat.verify` |
44
+ | Shipping a release, or recovering one | `release.deploy` |
45
+ | Observability, Sonar service, or a tunnel | `platform.operate` |
46
+ | An educational content unit | `content.generate` |
47
+ | Publishing an approved Git boundary | `git.publish` |
48
+
49
+ A request that names no owner, or two owners whose scopes differ materially, stops here with one
50
+ focused question naming the competing boundaries.
51
+
52
+ ## The loop
53
+
54
+ ```text
55
+ request/request.json -> validate-request.mjs -> agent writes response/ -> validate-response.mjs + the operator's validate.mjs -> route
56
+ ```
57
+
58
+ Routing reads `response.json` and nothing else:
59
+
60
+ 1. `done` advances the chain to the next step the workflow names; the next branch's `request.json`
61
+ points at this branch's outputs by explicit path.
62
+ 2. `waiting` runs the nested exchange the response awaits (`<exchange>/request` and `response` inside
63
+ the same branch), then resumes the same agent; sibling branches keep running.
64
+ 3. `blocked` reads `stop`, looks the code up in the merged registry (`operators/errors.json` plus the
65
+ operator's own `errors.json`) for its `domain`, and resolves that domain in `routing.json`:
66
+ - `operator` invokes the named operator, then returns here;
67
+ - `resume` re-enters the same operator in a new step, `request.json.resume` naming the blocked one;
68
+ - `user` stops and reports what the person must decide or publish;
69
+ - `external` stops and reports what outside the runtime must change.
70
+ A code whose disposition is `fallback` never blocks: the agent performs the fallback, records it
71
+ under `## Fallbacks taken`, and continues, unless the code's `unless` param says otherwise.
72
+
73
+ A response that fails either validator does not route. Prose in `response.md` does not route. Only a
74
+ validated field of `response.json` does.
75
+
76
+ `routing.json` is closed and checked: every domain an operator's stop codes hand to has exactly one
77
+ route, and no route names a domain no code reaches. A missing route is a build failure, not a
78
+ judgement call.
79
+
80
+ ## Progress
81
+
82
+ Every operator carries its own resume and fingerprint semantics, so this file holds no progress
83
+ counter and no handoff state. A `resume` route that returns `NO_PROGRESS` means the same input
84
+ reached the same wall: report the wall rather than trying again.
85
+
86
+ A cycle between two operators is valid only while the progress fingerprint changes. A repeated
87
+ fingerprint, or the same material finding twice, ends the loop and reports the smaller owner.
88
+
89
+ ## Authority
90
+
91
+ This file grants nothing. Every authority boundary is enforced by the operator's own `operator.md`
92
+ tables and `validate.mjs`, which this file cannot widen:
93
+
94
+ - `git.publish` has no requirement that can name a force push, a bypassed hook, a reset, a clean, a
95
+ stash, or a branch deletion; it merges the session branch, pushes non-force, and a conflict is
96
+ `NON_FAST_FORWARD` for a person.
97
+ - `release.deploy` and `platform.operate` require an `approval`; `release.deploy` runs only on a
98
+ `quality-verification` input.
99
+ - `uat.verify` runs only with a `requestedBy`, its account record refuses a password field, and its
100
+ validator rejects a credential-shaped string anywhere in what it writes.
101
+ - `frontend.presentation.resolve` and `frontend.surface.audit` may name only rule identifiers the bound
102
+ knowledge publishes; `frontend.source.apply` writes only classes in the resolved inventory.
103
+ - A source-writing operator commits only on `session/<sessionId>`; the person's branch is never touched.
104
+
105
+ If a mission seems to need more than an operator allows, that is the answer, not an obstacle to route
106
+ around.
107
+
108
+ ## Knowledge
109
+
110
+ Operators bind their own knowledge; this file does not preload it.
111
+
112
+ | Folder | Bound by |
113
+ | --- | --- |
114
+ | `knowledge/ui/composition/` | `frontend.direction.decide` |
115
+ | `knowledge/ui/presentation/` | `frontend.presentation.resolve` |
116
+ | `knowledge/ui/proof/` | `frontend.surface.audit` |
117
+ | `knowledge/patterns/fe/`, `knowledge/patterns/be/` | `frontend.source.apply`, `backend.source.apply` |
118
+ | `knowledge/grammars/<family>/` | every operator that composes that family |
119
+
120
+ English `.md` files are the only runtime authority. Same-stem `.vi.md` files are human mirrors and
121
+ never enter a context manifest, a dependency list, a validator input, or an operator binding.
122
+
123
+ ## Orchestration
124
+
125
+ One invocation of one operator is one agent, created fresh on the profile its `operator.json` names,
126
+ with the aliases its Context table declares and the tools its `operator.json` declares (`@tools/<id>` from `resources/tools.json`, one mode each) and nothing else. `resources/orchestrator.json`
127
+ fixes the rules: at most three agents at once, branches of one step never sharing a write alias,
128
+ dispatch by workflow and `routing.json`, hand-off only through `response.json` fields inside the
129
+ session (`state.json`, `step-N/parallel-M/{request,response}`), a session the orchestrator creates
130
+ first and deletes after `git.publish`. An agent never starts another agent; a nested exchange (a
131
+ critique, a review) is a second fresh agent the orchestrator spawns for a branch that paused with
132
+ `waiting`. `alias/alias.json` is the one place an alias resolves to a location, and `alias/INDEX.md` is
133
+ its readable map by zone (workspaces, grammar, knowledge, worktrees, remote, dynamic); an operator
134
+ reads only what its Context table names.
135
+
package/SKILL.vi.md ADDED
@@ -0,0 +1,128 @@
1
+ # StarCi
2
+
3
+ Một cửa vào, mười bốn operator, một bảng định tuyến đóng. File này chọn operator đầu tiên và sắp
4
+ xếp các operator còn lại. Nó không tự làm việc gì: không quyết một giá trị, không ghi source, không
5
+ phán xét một kết quả.
6
+
7
+ ## Chuẩn bị
8
+
9
+ 1. Đóng băng một phạm vi nhiệm vụ: đơn vị, đích, phần bao gồm và phần loại trừ, các gốc được ghi,
10
+ hiệu ứng ra bên ngoài, và thứ sẽ được tính là bằng chứng. Hai cách đọc làm đổi bất kỳ điểm nào
11
+ trong số đó là một câu hỏi tập trung, không phải một phỏng đoán.
12
+ 2. Chạy `workspace.bind` cho mọi nhiệm vụ có đọc hoặc ghi source đã route. Không thứ gì khác được
13
+ phép tự tìm checkout, và một thư mục trùng tên không bao giờ là thẩm quyền route.
14
+ 3. Tìm workflow trước: đọc `when` của mọi ví dụ trong `workflows/`. Khớp thì chạy đúng như đã ghi,
15
+ preset điền vào `request.json`. Không khớp thì tự ghép chuỗi từ bảng `## Kế tiếp` của các operator
16
+ theo luật trong `workflows/README.md` (input bắt buộc phải được sinh trước, không chung alias ghi
17
+ trong một bậc, vòng lặp có trần, có điểm kết thúc); chuỗi tự ghép đáng giữ thì thành ví dụ mới.
18
+ 4. Chọn operator đầu tiên của chuỗi đó. Chỉ đọc `operator.md` và `operator.json` của đúng
19
+ operator đó.
20
+ 5. Chạy operator đó, từ đầu tới cuối, trên đúng một profile mà `operator.json` của nó gọi tên dưới
21
+ `resources`, với đúng những quyền nó liệt kê. Một operator không có model khác, không thừa hưởng lượt nào,
22
+ và không có quyền nào mà assignment bỏ sót.
23
+
24
+ ## Cửa vào
25
+
26
+ | Yêu cầu nói về | Operator đầu tiên |
27
+ | --- | --- |
28
+ | Dự án nào, checkout nào, hay binding runtime nào | `workspace.bind` |
29
+ | Sản phẩm hứa gì, ai được hưởng, hỏng thì ra sao | `business.decide` |
30
+ | Ranh giới hệ thống, quyền sở hữu dữ liệu, hay tech stack | `architecture.decide` |
31
+ | Hành vi phía server, một hợp đồng API, lưu trữ, hay một job | `backend.source.apply` |
32
+ | Tạo mới, dựng lại, hay thiết kế lại một trang hoặc một surface | `frontend.direction.decide` |
33
+ | Một cây đã dựng xong lấy giá trị CSS nào | `frontend.presentation.resolve` |
34
+ | Ghi một cây đã resolve vào product source | `frontend.source.apply` |
35
+ | Một surface đã render có thật sự đứng vững không | `frontend.surface.audit` |
36
+ | Build, lint, typecheck, coverage, hay Sonar | `quality.verify` |
37
+ | Một người thật có hoàn thành được một hành trình thật không | `uat.verify` |
38
+ | Phát hành, hay khôi phục một bản phát hành | `release.deploy` |
39
+ | Observability, dịch vụ Sonar, hay một tunnel | `platform.operate` |
40
+ | Một đơn vị nội dung giáo dục | `content.generate` |
41
+ | Publish một ranh giới Git đã duyệt | `git.publish` |
42
+
43
+ Một yêu cầu không gọi tên chủ nào, hoặc gọi hai chủ có phạm vi khác nhau đáng kể, dừng lại ở đây với
44
+ một câu hỏi tập trung nêu tên các ranh giới đang cạnh tranh.
45
+
46
+ ## Vòng lặp
47
+
48
+ ```text
49
+ request/request.json -> validate-request.mjs -> agent ghi response/ -> validate-response.mjs + validate.mjs của operator -> định tuyến
50
+ ```
51
+
52
+ Định tuyến chỉ đọc `response.json`, không đọc gì khác:
53
+
54
+ 1. `done` đưa chuỗi tới bậc kế tiếp mà workflow gọi tên; `request.json` của nhánh sau trỏ tới output
55
+ của nhánh này bằng đường dẫn tường minh.
56
+ 2. `waiting` chạy cuộc trao đổi lồng mà response đang chờ (`<exchange>/request` và `response` trong
57
+ cùng nhánh), rồi cho chính agent đó chạy tiếp; các nhánh cùng bậc vẫn chạy.
58
+ 3. `blocked` đọc `stop`, tra mã trong sổ gộp (`operators/errors.json` cộng `errors.json` của chính
59
+ operator) lấy `domain`, rồi tra domain đó trong `routing.json`:
60
+ - `operator` gọi operator được nêu tên, rồi quay lại đây;
61
+ - `resume` vào lại chính operator đó ở một bậc mới, `request.json.resume` trỏ về nhánh bị chặn;
62
+ - `user` dừng và báo người phải quyết hoặc phải publish gì;
63
+ - `external` dừng và báo thứ gì ngoài runtime phải thay đổi.
64
+ Mã có cách xử lý `fallback` không bao giờ chặn: agent làm đúng fallback, ghi dưới
65
+ `## Fallbacks taken`, rồi chạy tiếp, trừ khi tham số `unless` của mã nói khác.
66
+
67
+ Response trượt một trong hai validator thì không định tuyến. Văn xuôi trong `response.md` không định
68
+ tuyến. Chỉ một trường đã validate của `response.json` mới định tuyến.
69
+
70
+ `routing.json` là bảng đóng và được kiểm: mọi domain mà mã dừng của một operator bàn giao tới đều có
71
+ đúng một route, và không route nào gọi tên một domain không mã nào chạm tới. Thiếu một route là lỗi
72
+ build, không phải chỗ để phán đoán.
73
+
74
+ ## Tiến độ
75
+
76
+ Mỗi operator tự mang ngữ nghĩa resume và fingerprint của nó, nên file này không giữ bộ đếm tiến độ
77
+ hay trạng thái handoff nào. Một route `resume` trả về `NO_PROGRESS` nghĩa là cùng một input đụng
78
+ cùng một bức tường: hãy báo bức tường thay vì thử lại.
79
+
80
+ Một vòng giữa hai operator chỉ hợp lệ khi fingerprint tiến độ còn thay đổi. Fingerprint lặp lại,
81
+ hoặc cùng một finding đáng kể xuất hiện hai lần, kết thúc vòng lặp và báo về chủ nhỏ hơn.
82
+
83
+ ## Thẩm quyền
84
+
85
+ File này không cấp gì cả. Mọi ranh giới thẩm quyền đều do các bảng trong `operator.md` và
86
+ `validate.mjs` của chính operator thực thi, và file này không nới rộng được:
87
+
88
+ - `git.publish` không có yêu cầu nào gọi tên được force push, hook bị bỏ qua, reset, clean, stash hay
89
+ xoá nhánh; nó merge nhánh phiên, push không force, và xung đột là `NON_FAST_FORWARD` cho người xử.
90
+ - `release.deploy` và `platform.operate` đòi `approval`; `release.deploy` chỉ chạy trên đầu vào
91
+ `quality-verification`.
92
+ - `uat.verify` chỉ chạy khi có `requestedBy`, bản ghi tài khoản từ chối trường password, và validator
93
+ của nó bác mọi chuỗi có hình dạng credential trong bất cứ thứ gì nó ghi.
94
+ - `frontend.presentation.resolve` và `frontend.surface.audit` chỉ được gọi tên những mã rule mà
95
+ knowledge được bind có publish; `frontend.source.apply` chỉ ghi class có trong inventory đã resolve.
96
+ - Operator ghi source chỉ commit trên `session/<sessionId>`; nhánh của người không bao giờ bị đụng.
97
+
98
+ Nếu một nhiệm vụ có vẻ cần nhiều hơn mức một operator cho phép, thì đó chính là câu trả lời, không
99
+ phải chướng ngại để lách.
100
+
101
+ ## Knowledge
102
+
103
+ Operator tự bind knowledge của mình; file này không nạp trước.
104
+
105
+ | Thư mục | Được bind bởi |
106
+ | --- | --- |
107
+ | `knowledge/ui/composition/` | `frontend.direction.decide` |
108
+ | `knowledge/ui/presentation/` | `frontend.presentation.resolve` |
109
+ | `knowledge/ui/proof/` | `frontend.surface.audit` |
110
+ | `knowledge/patterns/fe/`, `knowledge/patterns/be/` | `frontend.source.apply`, `backend.source.apply` |
111
+ | `knowledge/grammars/<họ>/` | mọi operator có dựng họ đó |
112
+
113
+ File `.md` tiếng Anh là authority duy nhất lúc chạy. File `.vi.md` cùng tên là bản đọc cho người và
114
+ không bao giờ vào context manifest, danh sách phụ thuộc, input của validator, hay binding của
115
+ operator.
116
+
117
+ ## Điều phối
118
+
119
+ Một lần gọi một operator là một agent, tạo mới trên profile mà `operator.json` của nó gọi tên, với
120
+ đúng những alias mà bảng Context của nó khai và những tool mà `operator.json` của nó khai (`@tools/<id>` từ `resources/tools.json`, mỗi tool một mode), không hơn. `resources/orchestrator.json` chốt
121
+ luật: tối đa ba agent cùng lúc, các nhánh cùng bậc không bao giờ chung alias ghi, điều phối theo
122
+ workflow và `routing.json`, bàn giao chỉ qua các trường của `response.json` trong phiên (`state.json`,
123
+ `step-N/parallel-M/{request,response}`), phiên do orchestrator tạo trước và xoá sau `git.publish`. Agent
124
+ không bao giờ khởi động agent khác; một cuộc trao đổi lồng (phản biện, review) là một agent mới do
125
+ orchestrator tạo cho nhánh đang `waiting`. `alias/alias.json` là nơi duy nhất một alias phân giải ra vị
126
+ trí, và `alias/INDEX.md` là bản đồ đọc được của nó theo vùng (workspaces, grammar, knowledge, worktrees,
127
+ remote, dynamic); operator chỉ đọc những gì bảng Context của nó gọi tên.
128
+
package/alias/INDEX.md ADDED
@@ -0,0 +1,104 @@
1
+ # Alias
2
+
3
+ Every location an operator may read, by alias, grouped by zone. Generated from `alias/alias.json` (the machine registry) and every `operator.json` by `scripts/generate-alias-doc.mjs`; `--check` runs inside `npm test`. An operator reads only the aliases its own `operator.md` Context table names; this page is the whole vocabulary those tables draw from. Resolution takes the longest registered prefix, a sub-path narrows an alias, and a segment in angle brackets is supplied by the invocation.
4
+
5
+ ## Workspaces — the working area
6
+
7
+ The working area: routed checkouts of the bound project and the declarations, routes, ports, and identity that locate them.
8
+
9
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
10
+ | --- | --- | --- | --- | --- | --- | --- |
11
+ | `@workspaces` | `<project>`, `<role>` | `<checkout:project/role> (any routed checkout named explicitly, for cross-project reads: @workspaces/nivo/fe)` | fingerprint + sourceHead (git rev-parse HEAD of the checkout) | — | — | A checkout of another project. The bound project's own are @workspaces/fe and @workspaces/be. |
12
+ | `@workspaces/be` | — | `<checkout:input.project.id/be> (diskPath from <Source>/.workspaces/local/routes/<project>/be/config.json); friendly segments: /husky, /package, /gates (see segments)` | fingerprint + sourceHead (git rev-parse HEAD of the checkout) | `backend.source.apply` | — | The routed backend checkout of the bound project. |
13
+ | `@workspaces/device-state` | — | `<Source>/.workspaces/device-state.json (sealed keys live in <Source>/.workspaces/local/credentials/*.key.enc and are bound by name, never read)` | fingerprint | — | — | Machine identity and the encrypted credential roster reference. |
14
+ | `@workspaces/fe` | — | `<checkout:input.project.id/fe> (diskPath from <Source>/.workspaces/local/routes/<project>/fe/config.json); friendly segments: /husky, /package, /gates, /grammar (see segments)` | fingerprint + sourceHead (git rev-parse HEAD of the checkout) | `frontend.source.apply` | — | The routed frontend checkout of the bound project. |
15
+ | `@workspaces/local/routes` | — | `<Source>/.workspaces/local/routes/<project>/<role>/config.json` | fingerprint | `workspace.bind` | — | Machine-local hydrated routes; project the declarations onto this disk. Ignored by Git. |
16
+ | `@workspaces/ports` | — | `<Source>/.workspaces/ports/<project>.json` | fingerprint | — | — | Port projection: project offset and application slots. Endpoints are derived, never typed. |
17
+ | `@workspaces/projects` | — | `<Source>/.workspaces/projects/<project>/<role>.json` | fingerprint | — | — | Portable route declarations, tracked. The only place a route is declared. |
18
+
19
+ ## Grammar — the package
20
+
21
+ The @starci/grammar package as the bound app resolves it: the only fact about what a component owns.
22
+
23
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
24
+ | --- | --- | --- | --- | --- | --- | --- |
25
+ | `@grammar` | `<family>` | `the @starci/grammar package as the bound app resolves it (file:packages/grammar inside @workspaces/fe today, source 0.4.2; @remote/npm publishes 0.3.0), narrowed to one family <family>: @grammar/core, @grammar/heritage, @grammar/offset-pop; @grammar/common is the shared layer every family imports` | package.json version + the resolved location's fingerprint (checkout head for file:, tarball integrity for npm) | — | — | The Grammar as it runs: Common renderers, props, owned relationships, data-contract claims, and the family's own CSS. The only fact about what a component owns. |
26
+
27
+ ## Knowledge — the law
28
+
29
+ Canonical law in this tree: universal UI law (ui), the family's taste (grammars), code conventions (patterns). Read only; edited by the owner.
30
+
31
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
32
+ | --- | --- | --- | --- | --- | --- | --- |
33
+ | `@knowledge/grammars` | — | `<Source>/.claude/knowledge/grammars/<family>/ (DNA.md generated from the package; idioms.md and playbook.md are the owner's taste; family.md holds the visual DNA and the gap table)` | fingerprint per file; DNA.md additionally binds the package version and checkout head it was generated from | — | — | How the family composes: the owner's taste (idioms, playbook) and what exists (DNA). Never the Grammar itself; where a taste row disagrees with @grammar, @grammar is the fact and the row is the finding. |
34
+ | `@knowledge/patterns` | — | `<Source>/.claude/knowledge/patterns/ (fe/, be/)` | fingerprint per file; rule inventory = every `## PREFIX-n` heading in the folder | — | — | Code conventions counted from the two live sources; a rule cites two real paths. |
35
+ | `@knowledge/ui` | — | `<Source>/.claude/knowledge/ui/ (composition/, presentation/, proof/; a sub-path narrows: @knowledge/ui/presentation)` | fingerprint per file; rule inventory = every `## PREFIX-n` heading in the folder | — | — | Universal UI law: what a tree must contain, which value an app boundary takes, what is only true once rendered. |
36
+
37
+ ## Worktrees — local authority and evidence
38
+
39
+ Machine-local authority and evidence outside any checkout: business heads, UAT pairs, debts, templates, the shared runtime owner.
40
+
41
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
42
+ | --- | --- | --- | --- | --- | --- | --- |
43
+ | `@worktrees/_templates` | — | `<Source>/.worktrees/_templates/ (businesses/, debts/, sessions/, uat/)` | fingerprint per file | — | — | Authority templates for new heads, debts, sessions, and UAT pairs. Consumed, never modified. |
44
+ | `@worktrees/businesses` | — | `<Source>/.worktrees/businesses/ (features/<featureId>/model.json; business-registry-v1.json is the head index; objects/sha256/ the content store)` | content address from business-registry-v1.json featureHeads.&lt;featureId&gt;.head, with authorityStatus | `business.decide` | — | Business promise heads. Its own git worktree; a head binds by content address even before its commit lands. |
45
+ | `@worktrees/debts` | — | `<Source>/.worktrees/debts/ (be.md, fe.md, per-item files)` | fingerprint per file | — | — | Owner-approved quality debts. A debt without a live approval here is not a debt. |
46
+ | `@worktrees/sessions` | — | `<Source>/.worktrees/sessions/<sessionId>/ (state.json; step-<N>/parallel-<M>/ branches, each with request/ and response/ — see @dynamic; central-runtime/ is the shared runtime owner registry outside any session)` | fingerprint per file read | `*` | — | The session container. Operators do not read it directly; they read @dynamic. |
47
+ | `@worktrees/sessions/central-runtime` | — | `<Source>/.worktrees/sessions/central-runtime/owner.json (generation-<n>-ready.json and logs/ beside it)` | fingerprint + generation | `platform.operate` | — | The shared runtime owner: generation, status, endpoints, health evidence. Callers consume, never own. |
48
+ | `@worktrees/uat` | — | `<Source>/.worktrees/uat/<flow>/ (flow.md: cases in order and named assertions; account.json: username, role, credential name of the single shared UAT password sealed at .stacks/<env>/secrets/uat.enc; seed/records.json and seed/expected.json; runs/<runId>/ append-only: result.json, verdicts.json, captures/<case>.png, sheet.png; latest -> the newest run). <case> narrows to one case of the flow` | fingerprint of snapshot.json and result.json | `uat.verify` | — | UAT authority per flow: the frozen flow, its dedicated account, its seed, and the append-only history of every run with the commit it verified. |
49
+
50
+ ## Remote — the internet
51
+
52
+ Internet. Registries, git remotes, image registries, CI runs, object storage. Read through a network; bound by version, digest, or observed head.
53
+
54
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
55
+ | --- | --- | --- | --- | --- | --- | --- |
56
+ | `@remote/ghcr` | `<image>` | `ghcr.io/<image>@<digest>` | digest | `release.deploy` | — | Immutable release images. A tag is never a binding; a digest is. |
57
+ | `@remote/git` | `<project>`, `<role>` | `the origin URL in @workspaces/local/routes/<project>/<role> (repository.gitRepository)` | observed remote head (git ls-remote) at invocation time | `git.publish` | — | The publication target; fast-forwardness is decided against this observation. |
58
+ | `@remote/github-actions` | `<runId>` | `GitHub Actions run <runId> of the routed repository` | run id + conclusion | — | — | CI evidence of a build or rollout, read only. |
59
+ | `@remote/minio` | `<contentId>`, `<locale>` | `MinIO object contents/<contentId>/<locale>.json through the routed runtime` | fingerprint of the fetched object | `content.generate` | — | Authored lesson content as served, not as drafted. |
60
+ | `@remote/npm` | `<package>` | `the npm registry entry for <package>, e.g. @remote/npm/@starci/grammar@0.3.0` | version + tarball integrity | — | — | Published packages. A version is the binding; latest never is. |
61
+
62
+ ## Dynamic — produced inside the session
63
+
64
+ Produced inside the current session by an earlier step and deleted with the session. Never exists before the run.
65
+
66
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
67
+ | --- | --- | --- | --- | --- | --- | --- |
68
+ | `@dynamic` | `<kind>` | `<Source>/.worktrees/sessions/<sessionId>/step-<N>/parallel-<M>/ — one branch of one step. request/request.json is the gate in (orchestrator writes it); response/ is the agent's: response.json (gate out), response.md and other markdown kinds, data/<name>.json, artifacts/<file>; a nested exchange adds <exchange>/request/ and <exchange>/response/. A kind is passed by explicit path in request.json inputs, from the session root. Dynamic files are passed as kinds (templates/kinds/<kind>), never as aliases. The session folder is created by the orchestrator and deleted when git.publish finishes; a blocked run keeps it for resume` | kind contract or schema under templates/kinds; response.json fields is the registry of what a branch produced | `*` | — | Everything produced inside the session and nothing that existed before it. Always dynamic; typed by kind. |
69
+
70
+ ## undefined
71
+
72
+
73
+
74
+ | Alias | Params | Resolves to | Bind | Writers | Bound by | Purpose |
75
+ | --- | --- | --- | --- | --- | --- | --- |
76
+ | `@tools/browsercontrol` | — | `resources/tools.json#tools.browsercontrol` | mode declared in operator.json → resources.tools; modes: never \| required | — | — | Drive a real browser against a served route: navigate, act, capture screenshots and DOM measurements. |
77
+ | `@tools/ci` | — | `resources/tools.json#tools.ci` | mode declared in operator.json → resources.tools; modes: never \| read \| dispatch | — | — | Observe or dispatch continuous-integration runs. |
78
+ | `@tools/container` | — | `resources/tools.json#tools.container` | mode declared in operator.json → resources.tools; modes: never \| read \| operate | — | — | Inspect or operate containers and images: compose services, GHCR images by digest. |
79
+ | `@tools/database` | — | `resources/tools.json#tools.database` | mode declared in operator.json → resources.tools; modes: never \| read \| namespaced-write | — | — | Read or write the product database for verification: seeds, fixtures, is_uat records. |
80
+ | `@tools/fileread` | — | `resources/tools.json#tools.fileread` | mode declared in operator.json → resources.tools; modes: never \| context-aliases | — | — | Read files and directories at the aliases the Context table names, at the frozen head. |
81
+ | `@tools/git` | — | `resources/tools.json#tools.git` | mode declared in operator.json → resources.tools; modes: never \| read \| commit-session-branch \| merge-and-push | — | — | Read and change repository state: heads, branches, worktrees, commits, merges, pushes. |
82
+ | `@tools/http` | — | `resources/tools.json#tools.http` | mode declared in operator.json → resources.tools; modes: never \| probe | — | — | Probe an endpoint: readiness, health, a served route, a GraphQL typename, a status page. |
83
+ | `@tools/imagegen` | — | `resources/tools.json#tools.imagegen` | mode declared in operator.json → resources.tools; modes: never \| judged \| required | — | — | Produce artwork: a digital image from an image model, made to one stated claim. Rendering HTML is the visualize tool, not this one. |
84
+ | `@tools/objectstorage` | — | `resources/tools.json#tools.objectstorage` | mode declared in operator.json → resources.tools; modes: never \| read \| write | — | — | Read or write objects in the content store (MinIO): curriculum, style references, published units. |
85
+ | `@tools/registry` | — | `resources/tools.json#tools.registry` | mode declared in operator.json → resources.tools; modes: never \| read | — | — | Read a package registry: the published Grammar, its version, its files. |
86
+ | `@tools/secrets` | — | `resources/tools.json#tools.secrets` | mode declared in operator.json → resources.tools; modes: never \| resolve-by-name | — | — | Resolve a sealed credential by name at the moment it is used; never read, print or store its value. |
87
+ | `@tools/shell` | — | `resources/tools.json#tools.shell` | mode declared in operator.json → resources.tools; modes: never \| declared-commands | — | — | Run declared commands: gates, builds, proofs, hooks, deployment plans. |
88
+ | `@tools/sourcewrite` | — | `resources/tools.json#tools.sourcewrite` | mode declared in operator.json → resources.tools; modes: never \| declared-write-set | — | — | Write files inside a routed checkout or an authority root. |
89
+ | `@tools/visualize` | — | `resources/tools.json#tools.visualize` | mode declared in operator.json → resources.tools; modes: never \| html | — | — | Render HTML for a person to look at: direction candidates, audit sheets, alternative comparisons, previews. No model grant is involved. |
90
+ | `@tools/websearch` | — | `resources/tools.json#tools.websearch` | mode declared in operator.json → resources.tools; modes: never \| bounded | — | — | Read public web pages to close one named gap in the evidence; results are references with URLs, never authority. |
91
+
92
+ ## Friendly segments inside a checkout
93
+
94
+ Human-friendly segments inside any checkout alias (@workspaces/fe, @workspaces/be, @workspaces/<project>/<role>), mapped to the exact path. Write the friendly word; the resolver substitutes the path.
95
+
96
+ | Segment | Resolves to |
97
+ | --- | --- |
98
+ | `husky` | `.husky/ (pre-commit, pre-push)` |
99
+ | `package` | `package.json (scripts, dependencies, the package version)` |
100
+ | `gates` | `package.json#scripts plus the configs it names (eslint.config.*, tsconfig*.json, jest.config.*/vitest.config.*, sonar-project.properties)` |
101
+ | `grammar` | `packages/grammar (the @starci/grammar source inside @workspaces/fe)` |
102
+ | `/branch/session` | `the session branch session/<sessionId> of that checkout, in its own git worktree prepared from the frozen head; the only branch a source-writing operator may commit to` |
103
+ | `/commit/<sha>` | `that checkout at one commit; how a later step names exactly what an earlier step wrote (response.json.commits[])` |
104
+