@therocketcode/gsd-core 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/gemini-extension.json +1 -1
- package/gsd-core/references/cicd-strategy.md +11 -0
- package/gsd-core/references/domain-modeling.md +2 -1
- package/gsd-core/references/infrastructure-strategy.md +4 -0
- package/gsd-core/templates/domain-model.md +4 -1
- package/gsd-core/workflows/cicd-strategy.md +5 -0
- package/gsd-core/workflows/infrastructure-strategy.md +5 -0
- package/gsd-core/workflows/model-domain.md +9 -2
- package/gsd-core/workflows/recommend-architecture.md +5 -1
- package/gsd-core/workflows/testing-strategy.md +3 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
3
|
"displayName": "GSD Core",
|
|
4
|
-
"version": "1.8.
|
|
4
|
+
"version": "1.8.4",
|
|
5
5
|
"description": "GSD Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "TheRocketCodeMX",
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gsd-core",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.4",
|
|
4
4
|
"description": "GSD Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads gsd's operating context into every Gemini CLI session.",
|
|
5
5
|
"contextFileName": "GEMINI.md"
|
|
6
6
|
}
|
|
@@ -77,6 +77,17 @@ The invariant at every rung (DORA + SRE Workbook + Charity Majors converge): **s
|
|
|
77
77
|
|
|
78
78
|
**Canary ANALYSIS prerequisites (SRE Workbook ch. 16 — all required):** ~**a dozen trustworthy, low-variance SLI-derived metrics**, real traffic volume that yields signal on a 1–5% slice, and deploy frequency exceeding human attention — on top of repeatable builds and automated deploys. Below that: rolling deploy + health checks + one-command rollback. Use "the simplest model that meets your technical and business objectives." Plain blue-green is a "before/after canary" — risky because time is the largest source of metric variance.
|
|
79
79
|
|
|
80
|
+
## Publishing packages — the deploy ladder for shipped software
|
|
81
|
+
|
|
82
|
+
When the product ships as packages/binaries (CLI, library, SDK), the "deployment ladder" IS the publishing pipeline:
|
|
83
|
+
|
|
84
|
+
- **Tag-driven releases**: version tag → one release workflow builds, tests, publishes everything (never publish from a laptop; never build different artifacts per registry from different commits).
|
|
85
|
+
- **PyPI: Trusted Publishing** (OIDC — the official PyPA standard): no long-lived API tokens; the workflow identity is the credential, with the repo/workflow pinned on the PyPI side (the publishing analog of the pinned `sub`).
|
|
86
|
+
- **npm: `npm publish --provenance`** on CI — provenance attestation links the package to its source commit and workflow.
|
|
87
|
+
- **crates.io: scoped tokens** (no OIDC support yet) — token scoped to the crate(s), stored in an **environment-protected secret** with required reviewers on the release environment; rotate on release-process changes.
|
|
88
|
+
- **Signed/attested artifacts**: GitHub artifact attestations (free) or cargo-dist/goreleaser-class tooling for binaries + checksums; full cosign ceremony stays deferred until artifacts cross trust boundaries.
|
|
89
|
+
- **Release environment protection + manual dispatch** for anything that spends money or publishes — doubles as the fork-PR secrets-safety rule (publish workflows never run on fork PRs).
|
|
90
|
+
|
|
80
91
|
## Supply-chain table stakes (small team — all free, each ≤ hours, each counters a real 2023–25 attack)
|
|
81
92
|
|
|
82
93
|
1. **SHA-pin all third-party actions + Dependabot updating the pins.** tj-actions/changed-files (Mar 2025, **CVE-2025-30066**): attacker retroactively moved version tags to a malicious secrets-dumping commit, 23,000+ repos hit — tag pinning gave zero protection. Dependabot updates SHA pins with version comments, so "pins go stale" is solved.
|
|
@@ -33,11 +33,12 @@ Classify each area of the system. This is the single highest-leverage output —
|
|
|
33
33
|
| **Supporting** | Necessary, not differentiating. Tightly coupled to the core. | "Good enough," build simply or buy-and-extend. | Onboarding flows, internal admin, notifications |
|
|
34
34
|
| **Generic** | Commodity every business needs; no edge. | Buy / off-the-shelf / library. | Auth, billing, email, logging, tax calculation |
|
|
35
35
|
|
|
36
|
-
###
|
|
36
|
+
### Four nuances that prevent misclassification
|
|
37
37
|
|
|
38
38
|
1. **Core = differentiating AND complex — not just complex (and not merely *critical* or *regulated*).** A complex-, critical-, or regulated-but-*generic* subdomain (tax, identity/auth, encryption, compliance) is a **buy**, not a build. Difficulty, security-criticality, and regulatory burden do not make something core — only competitive differentiation does. Don't invest core-grade effort there.
|
|
39
39
|
2. **Generic ≠ low quality.** "Generic" means *not differentiating*, not *low effort*. A battle-tested auth library is high-quality and generic.
|
|
40
40
|
3. **Watch for CRUD that will grow business rules.** The dangerous case is an app that "starts as a UI over the database, then evolves into real domain logic." Whenever an area is *described* as simple/CRUD — whatever type is being claimed — probe future features: *will this accumulate invariants and rules?* If yes, treat it as (emerging) core/supporting, not generic. "Core but just CRUD" is self-contradictory — challenge which half is wrong.
|
|
41
|
+
4. **The strategic instrument — when the triad has no slot.** Some subdomains are venture-critical without being product-differentiating: a benchmark/eval suite, an open standard, a public SDK ecosystem, an internal framework — things whose value is *positional* (credibility, ecosystem, a standard you steward) and whose endgame may be neutrality or giveaway. Forcing these into the triad misallocates: "supporting" understates them, "core" steers tactical-DDD richness at the wrong place (you don't give away your core). Classify them as their **own candidate context** annotated *instrument — venture-critical*, allocate rigor by their derived complexity, and apply the rule: **core-grade rigor ≠ core**. The differentiation test stays structural: the core is what's hard to copy for *technical* reasons; an instrument's moat is usually *positional* (reputation, neutrality), and positions belong in their own context with their own destiny.
|
|
41
42
|
|
|
42
43
|
### What "complex" means — the complexity-signals rubric
|
|
43
44
|
|
|
@@ -8,6 +8,10 @@ The empirically safe prior, not a bias: real Kubernetes clusters average **8–1
|
|
|
8
8
|
|
|
9
9
|
The three inputs every crossover keys off: **traffic shape** (idle %, burst ratio), **team size**, **monthly compute spend**. Get these before recommending anything.
|
|
10
10
|
|
|
11
|
+
## Shipped software, not a service (check this FIRST)
|
|
12
|
+
|
|
13
|
+
When the product is **user-operated** — a CLI, library, desktop app, self-hosted binary — the operated-infrastructure footprint may legitimately be ≈ zero, and walking the compute ladder for it is over-engineering by this reference's own rule. The decisions shift to: **CI compute** (often the only compute you pay for — API-bound workloads need spend guardrails, not bigger runners), **release & distribution channels** (registries, GitHub Releases, installers — see the publishing section of `cicd-strategy.md`), **docs/results hosting** (Pages-class static hosting), and **API-spend guardrails** (provider billing alerts + workload kill-switches). Record the operated-service ladder only as **promotion-trigger material** for a future hosted tier — triggered, never pre-provisioned.
|
|
14
|
+
|
|
11
15
|
## The compute decision ladder
|
|
12
16
|
|
|
13
17
|
| Rung | Wins when | Move up when |
|
|
@@ -9,7 +9,7 @@ The shared vocabulary. Use these terms consistently in code, docs, and conversat
|
|
|
9
9
|
|
|
10
10
|
| Term | Definition | Used by | Aliases / not to be confused with |
|
|
11
11
|
|------|-----------|---------|-----------------------------------|
|
|
12
|
-
| [Term] | [What it means in THIS domain] | [team / users / both] | [aliases, or the term it's often confused with] |
|
|
12
|
+
| [Term] | [What it means in THIS domain] | [team / end-users / both — for dev tools: maintainers vs developer-users] | [aliases, or the term it's often confused with] |
|
|
13
13
|
|
|
14
14
|
> Polysemes (one word, two meanings across areas) are flagged here — they usually mark a bounded-context boundary.
|
|
15
15
|
|
|
@@ -32,6 +32,9 @@ Strategic classification — drives where to invest and (downstream) the archite
|
|
|
32
32
|
**Generic** — commodity; buy / off-the-shelf / library:
|
|
33
33
|
- [Subdomain] — [why]
|
|
34
34
|
|
|
35
|
+
**Instrument — venture-critical (own context; only when one exists)** — positional value (standard/benchmark/ecosystem), not product differentiation; core-grade rigor ≠ core:
|
|
36
|
+
- [Subdomain] — [its own destiny, e.g. "community standard — planned neutrality"]
|
|
37
|
+
|
|
35
38
|
> Misclassification check applied: each Generic/CRUD area was probed for future business rules. Areas expected to accumulate invariants are marked emerging-core/supporting, not generic.
|
|
36
39
|
|
|
37
40
|
## Bounded Contexts
|
|
@@ -40,6 +40,9 @@ cat .planning/PROJECT.md 2>/dev/null || true
|
|
|
40
40
|
|
|
41
41
|
**Read `@~/.claude/gsd-core/references/cicd-strategy.md` now** — it defines the GHA-default platform decision, OIDC-with-pinned-`sub`, the secrets split, the tier→stage mapping with the ≤10-min PR budget, the flaky canon, the merge-queue trigger, the deployment ladder, the free-six supply-chain table stakes, and the anti-pattern table.
|
|
42
42
|
|
|
43
|
+
**Grounding maturity governs elicitation depth.** When upstream artifacts (spec, ADR, strategies, research) already answer a step, draft-from-docs and present for confirmation — cite the source, don't re-interview. Reserve questions for genuine decision points and contradictions. Honor a posture stated in `$ARGUMENTS` without re-asking.
|
|
44
|
+
|
|
45
|
+
|
|
43
46
|
**If `NO_TEST_STRATEGY`:** tell the user "No test strategy found — the pipeline mapping is much better with one. (Consider `/gsd:testing-strategy` first.)" If they decline, proceed with generic tiers (small/unit → PR; medium/integration → merge; large/e2e → nightly) and note the gap in the output. From TEST-STRATEGY.md, extract: the per-subdomain level emphasis, the persistent e2e smoke list (the 3–7 flows), and the mutation-testing targets. From INFRA-STRATEGY.md / ADR / PROJECT.md, extract: target cloud + deploy target, repo host, team size, and blast radius (payments/PII/data = high). Ask only what's missing (header "Context"): team size, blast radius, expected merge volume.
|
|
44
47
|
|
|
45
48
|
## Step 3: Platform choice
|
|
@@ -77,6 +80,8 @@ Map the tiers from TEST-STRATEGY.md onto the three stages (this is Google's stat
|
|
|
77
80
|
|
|
78
81
|
## Step 6: Deployment ladder rung
|
|
79
82
|
|
|
83
|
+
**Shipped-software route:** if the product ships as packages/binaries rather than an operated service, the ladder rung IS the publishing pipeline — walk the reference's "Publishing packages" section instead (tag-driven releases, PyPI Trusted Publishing, npm provenance, crates.io scoped+environment-protected tokens, attestations, fork-PR exclusion). The service ladder applies only to any future hosted tier, as promotion-trigger material.
|
|
84
|
+
|
|
80
85
|
Pick the rung from **team size + blast radius** (from Step 2), using the reference's ladder. Build-once/promote-same-artifact and one-command rollback are invariants at every rung.
|
|
81
86
|
|
|
82
87
|
- **Solo/small, low blast radius:** trunk-based + one automated deploy path + free platform PR previews (+ Neon-style DB branch per preview if Postgres) + one-command rollback. **No staging environment.**
|
|
@@ -41,6 +41,9 @@ cat .planning/TEST-STRATEGY.md 2>/dev/null || true
|
|
|
41
41
|
|
|
42
42
|
**Read `@~/.claude/gsd-core/references/infrastructure-strategy.md` now** — it defines the compute ladder with quantified move-up triggers, the crossover numbers (Fargate-vs-EC2, the CAST AI utilization data, the <4-engineers floor), the per-cloud asymmetries and equivalences table, the observability floor, the when-you-actually-need triggers, the IaC floor, the anti-patterns, and the meta-tell.
|
|
43
43
|
|
|
44
|
+
**Grounding maturity governs elicitation depth.** When upstream artifacts (spec, ADR, strategies, research) already answer a step, draft-from-docs and present for confirmation — cite the source, don't re-interview. Reserve questions for genuine decision points and contradictions. Honor a posture stated in `$ARGUMENTS` without re-asking.
|
|
45
|
+
|
|
46
|
+
|
|
44
47
|
From the artifacts, extract: **scale expectations + traffic shape** (PRODUCT-BRIEF), **deployment topology** — how many independently deployed components (the ADR; monolith → one service is the normal answer), and **CI environment needs** (TEST-STRATEGY: test containers, e2e environments). **If `NO_ADR`:** tell the user "No architecture decision found — I'll ask briefly. (Consider `/gsd:recommend-architecture` first.)" then ask: how many deployables, and is anything stateful self-managed?
|
|
45
48
|
|
|
46
49
|
Then gather the three inputs every crossover keys off (AskUserQuestion, header "Shape", or a text list): **traffic shape** (idle most of the day? bursty? steady?), **team size** (engineers who'd touch infra), and **expected monthly compute spend** (or "no idea" — fine, the default rung is the safe prior).
|
|
@@ -53,6 +56,8 @@ If constrained: take it — the ladder is cloud-portable; use the reference's eq
|
|
|
53
56
|
|
|
54
57
|
## Step 4: Compute rung (walk the ladder per component)
|
|
55
58
|
|
|
59
|
+
**Shipped-software check first:** if the product is user-operated (CLI/library/desktop/self-hosted binary), do NOT walk the ladder for the product itself — the reference's "Shipped software, not a service" section governs: CI compute + distribution + docs hosting + spend guardrails; the service ladder becomes promotion-trigger material only.
|
|
60
|
+
|
|
56
61
|
For each deployable component from the ADR topology, walk the reference's ladder. **Default = serverless containers** (Cloud Run / ECS+Fargate / Container Apps). Only place a component on another rung when a concrete trigger from the reference fires — and record the trigger next to the rung.
|
|
57
62
|
|
|
58
63
|
- **Rung-down check (static/FaaS):** pre-renderable frontends → static/edge hosting; pure event-glue (webhooks, queue consumers, cron) → FaaS is fine *until* the FaaS→containers triggers: >15-min runs, WebSockets/streaming, connection pools / in-memory caches, or ~>15M invocations/month sub-second.
|
|
@@ -45,6 +45,8 @@ From the project docs, build an internal draft:
|
|
|
45
45
|
- Which nouns/verbs recur (candidate ubiquitous-language terms)?
|
|
46
46
|
- Are there distinct business areas or user roles (candidate subdomains)?
|
|
47
47
|
|
|
48
|
+
**Grounding maturity governs elicitation depth.** When the upstream docs are mature (a design spec, research corpus, or detailed brief already forged the vocabulary and areas), default every step to **draft-from-docs + confirm**: present complete drafts for correction, state which docs grounded them, and reserve actual questions for *genuine decision points* — contested classifications, the one-core call, complexity contradictions. The 2–3 probing rounds below are for thin grounding (a bare PROJECT.md), not a re-interview of what the docs already answer. Honor a posture stated in `$ARGUMENTS` without re-asking.
|
|
49
|
+
|
|
48
50
|
**Check for an existing model:**
|
|
49
51
|
```bash
|
|
50
52
|
ls .planning/DOMAIN-MODEL.md >/dev/null 2>&1 && echo "EXISTS" || echo "NEW"
|
|
@@ -77,6 +79,7 @@ Language — I drafted these terms: [list]. What needs fixing?
|
|
|
77
79
|
3. Let me describe the vocabulary from scratch
|
|
78
80
|
Reply with a number, or just tell me the corrections.
|
|
79
81
|
```
|
|
82
|
+
**Text-mode batching:** when several questions are pending, present them as numbered *sections* in ONE message (each with its own option list) and accept combined replies ("1, 2" = first option of Q1, second of Q2) or free text per section — don't serialize one message per question.
|
|
80
83
|
|
|
81
84
|
## Step 4: Subdomain distillation (the pivotal step)
|
|
82
85
|
|
|
@@ -90,6 +93,7 @@ For each candidate area, classify it and **capture the rationale**. Apply the mi
|
|
|
90
93
|
1. **Differentiation — not difficulty — decides Core.** If the user justifies Core by *difficulty, criticality, security, risk, or regulatory burden* rather than by competitive differentiation, test it: "Is this actually your competitive advantage, or a hard/critical-but-standard problem (e.g., tax, auth, encryption, compliance) you could buy?" If standard → **Generic (buy)**, not core. Critical ≠ differentiating; regulated ≠ differentiating.
|
|
91
94
|
2. **CRUD that will grow.** Whenever an area is *described* as CRUD/simple/"just forms and dates" — regardless of the type being claimed — ask: "Will this accumulate real business rules and invariants over time, or stay simple data-in/data-out?" If it will grow → mark it **emerging Supporting** (the default for growing areas), not generic. It is Core only if it is itself the competitive differentiator — and there is normally exactly one of those. Claiming Core *while* describing it as trivial is a contradiction — Core means differentiating AND complex; probe which half is wrong.
|
|
92
95
|
3. **Generic ≠ low quality.** Note to the user that "generic" means *not differentiating*, not *low effort*.
|
|
96
|
+
4. **Strategic instrument.** A venture-critical area that is NOT product-differentiating (a benchmark/eval suite, an open standard, a public SDK ecosystem — value is positional, endgame may be neutrality/giveaway) doesn't fit the triad: record it as its **own candidate context** annotated *instrument — venture-critical*, rigor allocated by its derived complexity. **Core-grade rigor ≠ core** — you don't give away your core.
|
|
93
97
|
|
|
94
98
|
**Complexity is derived, never asked.** For each non-generic area, elicit 2–3 of the reference rubric's five signals (invariants; lifecycle depth; derivation/optimization; temporal logic; policy variance) — usually one question: "What rules can never be broken here, and what's the hardest decision this area makes?" — then rate per the rubric, recording fired signals in the rationale cell. **Tripwire: Core+low is a contradiction** — probe: "If it's your differentiator but has no complex rules, what makes it hard to copy?" — it's either not core, or not low. Generic+high is a buy-harder signal.
|
|
95
99
|
|
|
@@ -141,9 +145,11 @@ DOMAIN-MODEL.md written — strategic domain foundation set.
|
|
|
141
145
|
Subdomains: [N] ([core] core · [supporting] supporting · [generic] generic)
|
|
142
146
|
Bounded contexts: [N] (or "deferred")
|
|
143
147
|
|
|
144
|
-
Next: /gsd:
|
|
148
|
+
Next: /gsd:recommend-architecture (uses the subdomain complexity) → testing → planning
|
|
145
149
|
```
|
|
146
150
|
|
|
151
|
+
**Roadmap reconciliation:** ROADMAP.md was created before this model existed. Scan it — if a finding invalidates or reshapes a phase (a phase straddling two candidate contexts, a buy-decision making a build-phase moot, a core needing an earlier walking-skeleton), SAY SO explicitly and offer `/gsd:phase --edit` (or a roadmap refresh — the roadmapper re-reads discovery artifacts). Never leave a known contradiction between the model and the roadmap unspoken.
|
|
152
|
+
|
|
147
153
|
</process>
|
|
148
154
|
|
|
149
155
|
<critical_rules>
|
|
@@ -163,5 +169,6 @@ Next: /gsd:plan-phase (planning will use the subdomain complexity to shape arc
|
|
|
163
169
|
- Bounded contexts surfaced (with `--event-storming`), candidate-recorded, or explicitly deferred
|
|
164
170
|
- No architecture prescribed
|
|
165
171
|
- DOMAIN-MODEL.md written from the template and committed (when commit_docs is true)
|
|
166
|
-
-
|
|
172
|
+
- Roadmap reconciliation: contradictions with ROADMAP.md surfaced explicitly (revision offered, never silent)
|
|
173
|
+
- User directed to /gsd:recommend-architecture
|
|
167
174
|
</success_criteria>
|
|
@@ -38,6 +38,8 @@ cat .planning/DOMAIN-MODEL.md 2>/dev/null || true
|
|
|
38
38
|
|
|
39
39
|
**Read `@~/.claude/gsd-core/references/architecture-decision.md` now** — it defines the two axes, the rung-signals, the "tall enough" gates, the Hard-Parts disintegrators/integrators, and the over-/under-engineering meta-tell.
|
|
40
40
|
|
|
41
|
+
**Grounding maturity governs elicitation depth.** When upstream artifacts (DOMAIN-MODEL, a design spec, research) already answer a question below, draft-from-docs and present for confirmation — cite the source, don't re-interview. Reserve `AskUserQuestion` for genuine decision points: contested rungs, gate answers the docs don't record, and contradictions (the reconcile rule still ALWAYS runs). Honor a posture stated in `$ARGUMENTS` without re-asking.
|
|
42
|
+
|
|
41
43
|
**If `NO_DOMAIN_MODEL`:** tell the user "No domain model found — I'll ask the complexity questions directly. (Consider `/gsd:model-domain` first for a sharper result.)" Then gather, per major area: is it core/supporting/generic, and how complex (rich rules vs CRUD)?
|
|
42
44
|
|
|
43
45
|
From DOMAIN-MODEL.md (or the answers): extract each subdomain's type + complexity, **plus** the bounded contexts (owns / talks-to), the context-map relationships, and any flagged polysemes — Step 4.5 consumes them. The **core** subdomain's complexity is the primary driver of Axis A.
|
|
@@ -126,9 +128,11 @@ ADR-NNNN written — architecture decided.
|
|
|
126
128
|
Fitness functions: [N] to enforce boundaries
|
|
127
129
|
Promotion triggers: [N] recorded — re-check at /gsd:new-milestone
|
|
128
130
|
|
|
129
|
-
Next: /gsd:
|
|
131
|
+
Next: /gsd:testing-strategy (test shape follows this architecture) → plan-phase
|
|
130
132
|
```
|
|
131
133
|
|
|
134
|
+
**Roadmap reconciliation:** ROADMAP.md predates this ADR. Scan it against the module map and topology — if a phase straddles module seams, the walking skeleton is missing/misplaced, or a buy-decision moots a build-phase, SAY SO explicitly and offer `/gsd:phase --edit` (or a roadmap refresh — the roadmapper re-reads discovery artifacts). Never leave a known ADR↔roadmap contradiction unspoken.
|
|
135
|
+
|
|
132
136
|
</process>
|
|
133
137
|
|
|
134
138
|
<critical_rules>
|
|
@@ -41,6 +41,9 @@ cat TESTING-STANDARDS.md 2>/dev/null || true
|
|
|
41
41
|
|
|
42
42
|
**Read `@~/.claude/gsd-core/references/test-strategy.md` now** — it defines behavior-over-implementation, sociable-by-default, test-once-at-cheapest-level, shape-follows-architecture (size axis), the gnarly-bits list, persistent-vs-transient e2e, and coverage-as-floor + mutation.
|
|
43
43
|
|
|
44
|
+
**Grounding maturity governs elicitation depth.** When upstream artifacts (spec, ADR, strategies, research) already answer a step, draft-from-docs and present for confirmation — cite the source, don't re-interview. Reserve questions for genuine decision points and contradictions. Honor a posture stated in `$ARGUMENTS` without re-asking.
|
|
45
|
+
|
|
46
|
+
|
|
44
47
|
**If `NO_ADR`:** tell the user "No architecture decision found — I'll ask briefly. (Consider `/gsd:recommend-architecture` first.)" Then, per major subdomain, get its rung (Transaction Script / Domain Model / Hexagonal / CQRS / Event Sourcing) and whether it's DB/integration-bound. Otherwise extract each subdomain's rung from the ADR.
|
|
45
48
|
|
|
46
49
|
## Step 3: Derive the shape FROM the architecture (per subdomain)
|
package/package.json
CHANGED