hstack 0.16.0 → 0.17.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.
- package/CHANGELOG.md +37 -0
- package/README.md +73 -163
- package/VERSION +1 -1
- package/dist/commands/doctor.js +18 -8
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +7 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.js +9 -2
- package/dist/commands/update.js.map +1 -1
- package/dist/lib/descriptions.js +10 -17
- package/dist/lib/descriptions.js.map +1 -1
- package/dist/lib/wire.js +166 -138
- package/dist/lib/wire.js.map +1 -1
- package/dist/manifest.js +41 -29
- package/dist/manifest.js.map +1 -1
- package/package.json +3 -4
- package/template/.claude/agents/adversarial-reviewer.md +42 -50
- package/template/.claude/agents/app-architect.md +44 -96
- package/template/.claude/agents/data-architect.md +46 -89
- package/template/.claude/agents/test-strategist.md +39 -68
- package/template/.claude/skills/hstack-adr-new/SKILL.md +23 -73
- package/template/.claude/skills/hstack-adversarial-review/SKILL.md +46 -152
- package/template/.claude/skills/hstack-adversarial-review/references/finding-categories.md +80 -103
- package/template/.claude/skills/hstack-app-architecture/SKILL.md +43 -68
- package/template/.claude/skills/hstack-commit/SKILL.md +27 -68
- package/template/.claude/skills/hstack-data-architecture/SKILL.md +34 -56
- package/template/.claude/skills/hstack-promote/SKILL.md +55 -0
- package/template/.claude/skills/hstack-story/SKILL.md +58 -0
- package/template/.claude/skills/hstack-test-audit/SKILL.md +64 -0
- package/template/.claude/skills/hstack-wrap/SKILL.md +48 -0
- package/template/.claude/skills/hstack-wrap/references/pr-description.md +45 -0
- package/template/KERNEL.md +75 -318
- package/template/templates/adr.md +2 -18
- package/template/templates/app-architecture.md +38 -50
- package/template/templates/data-architecture.md +38 -89
- package/template/templates/infrastructure.md +54 -148
- package/template/templates/roadmap.md +6 -12
- package/template/templates/story.md +7 -13
- package/template/templates/tech-debt.md +2 -37
- package/template/templates/tech-stack.md +2 -12
- package/template/.claude/agents/data-specialist.md +0 -81
- package/template/.claude/agents/implementer.md +0 -97
- package/template/.claude/agents/kernel-fit-analyst.md +0 -129
- package/template/.claude/agents/planner.md +0 -75
- package/template/.claude/agents/product-discovery.md +0 -129
- package/template/.claude/agents/product-manager.md +0 -76
- package/template/.claude/agents/researcher.md +0 -87
- package/template/.claude/agents/security-reviewer.md +0 -88
- package/template/.claude/agents/spec-author.md +0 -89
- package/template/.claude/agents/stack-architect.md +0 -108
- package/template/.claude/agents/ui-ux-briefer.md +0 -75
- package/template/.claude/agents/verifier.md +0 -81
- package/template/.claude/skills/hstack-branch/SKILL.md +0 -76
- package/template/.claude/skills/hstack-brownfield-init/SKILL.md +0 -131
- package/template/.claude/skills/hstack-change-new/SKILL.md +0 -84
- package/template/.claude/skills/hstack-change-plan/SKILL.md +0 -108
- package/template/.claude/skills/hstack-configure/SKILL.md +0 -99
- package/template/.claude/skills/hstack-coord/SKILL.md +0 -95
- package/template/.claude/skills/hstack-data-review/SKILL.md +0 -93
- package/template/.claude/skills/hstack-finalize/SKILL.md +0 -140
- package/template/.claude/skills/hstack-flag/SKILL.md +0 -99
- package/template/.claude/skills/hstack-greenfield-init/SKILL.md +0 -148
- package/template/.claude/skills/hstack-help/SKILL.md +0 -153
- package/template/.claude/skills/hstack-implement/SKILL.md +0 -155
- package/template/.claude/skills/hstack-kernel-fit-promote/SKILL.md +0 -125
- package/template/.claude/skills/hstack-kernel-fit-scan/SKILL.md +0 -142
- package/template/.claude/skills/hstack-kernel-fit-scan/references/slack-setup.md +0 -42
- package/template/.claude/skills/hstack-kernel-fit-triage/SKILL.md +0 -121
- package/template/.claude/skills/hstack-module-spec/SKILL.md +0 -78
- package/template/.claude/skills/hstack-product-discovery/SKILL.md +0 -75
- package/template/.claude/skills/hstack-research/SKILL.md +0 -115
- package/template/.claude/skills/hstack-scaffold/SKILL.md +0 -113
- package/template/.claude/skills/hstack-security-review/SKILL.md +0 -95
- package/template/.claude/skills/hstack-ship/SKILL.md +0 -119
- package/template/.claude/skills/hstack-stack-decide/SKILL.md +0 -81
- package/template/.claude/skills/hstack-story-draft/SKILL.md +0 -92
- package/template/.claude/skills/hstack-tech-debt-new/SKILL.md +0 -95
- package/template/.claude/skills/hstack-tech-debt-resolve/SKILL.md +0 -123
- package/template/.claude/skills/hstack-tech-debt-stale/SKILL.md +0 -86
- package/template/.claude/skills/hstack-tech-debt-wontfix/SKILL.md +0 -77
- package/template/.claude/skills/hstack-telemetry/SKILL.md +0 -73
- package/template/.claude/skills/hstack-test-plan/SKILL.md +0 -159
- package/template/.claude/skills/hstack-ui-brief/SKILL.md +0 -81
- package/template/.claude/skills/hstack-verify/SKILL.md +0 -128
- package/template/scripts/compute-merge-readiness.mjs +0 -780
- package/template/scripts/coord/coord_scan.py +0 -681
- package/template/scripts/run-gates.sh +0 -388
- package/template/scripts/telemetry/__init__.py +0 -6
- package/template/scripts/telemetry/insights/__init__.py +0 -0
- package/template/scripts/telemetry/insights/contract_drift.py +0 -137
- package/template/scripts/telemetry/insights/kernel_fit.py +0 -438
- package/template/scripts/telemetry/insights/overengineering.py +0 -115
- package/template/scripts/telemetry/insights/quality_outcomes.py +0 -131
- package/template/scripts/telemetry/insights/token_economics.py +0 -302
- package/template/scripts/telemetry/insights/workflow_shape.py +0 -198
- package/template/scripts/telemetry/parsers/__init__.py +0 -0
- package/template/scripts/telemetry/parsers/bodies.py +0 -87
- package/template/scripts/telemetry/parsers/commits.py +0 -219
- package/template/scripts/telemetry/parsers/frontmatter.py +0 -322
- package/template/scripts/telemetry/parsers/sidecars.py +0 -61
- package/template/scripts/telemetry/parsers/transcripts.py +0 -294
- package/template/scripts/telemetry/render.py +0 -460
- package/template/scripts/telemetry/report.py +0 -150
- package/template/scripts/telemetry/run_kernel_fit.py +0 -95
- package/template/scripts/telemetry/session_id.py +0 -139
- package/template/scripts/validate-spec.mjs +0 -3303
- package/template/templates/adversarial-review.md +0 -54
- package/template/templates/bootstrap.md +0 -105
- package/template/templates/change-spec.md +0 -82
- package/template/templates/ci-cd.md +0 -41
- package/template/templates/coord-message.md +0 -56
- package/template/templates/data-review.md +0 -54
- package/template/templates/discovery/brainstorm.md +0 -69
- package/template/templates/discovery/forcing-questions.md +0 -76
- package/template/templates/discovery/project-brief.md +0 -53
- package/template/templates/figma-handoff.md +0 -38
- package/template/templates/glossary.md +0 -20
- package/template/templates/hardening-checklist.md +0 -73
- package/template/templates/incident-runbook.md +0 -57
- package/template/templates/kernel-fit-finding.md +0 -63
- package/template/templates/kernel-fit-flag.md +0 -52
- package/template/templates/module-spec.md +0 -49
- package/template/templates/persona.md +0 -38
- package/template/templates/plan.md +0 -53
- package/template/templates/product-brief.md +0 -56
- package/template/templates/security-review.md +0 -63
- package/template/templates/telemetry-sidecar.md +0 -227
- package/template/templates/test-plan.md +0 -119
- package/template/templates/threat-model.md +0 -54
- package/template/templates/ui-brief.md +0 -49
- package/template/templates/verification.md +0 -63
- package/template/templates/vision.md +0 -34
|
@@ -1,77 +1,76 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: app-architecture
|
|
3
3
|
type: app-architecture
|
|
4
|
-
status: draft # draft | current | needs-refresh | archived
|
|
5
|
-
owner: <git-handle>
|
|
6
|
-
derived-from: [product-brief, data-architecture]
|
|
7
|
-
downstream: [threat-model, hardening-checklist, tech-stack, module-spec/*]
|
|
8
|
-
created: <YYYY-MM-DD>
|
|
9
4
|
updated: <YYYY-MM-DD>
|
|
10
|
-
schema-version: 1
|
|
11
5
|
---
|
|
12
6
|
|
|
13
7
|
## 1. Module Map
|
|
14
8
|
|
|
15
|
-
_The
|
|
9
|
+
_The modules, what each owns, and what reaches them. `Critical: yes` means the kernel's
|
|
10
|
+
mandatory-test rule applies to this module's paths._
|
|
16
11
|
|
|
17
|
-
**
|
|
12
|
+
_The **Exposure** column is the exposure map. One line per entry point: `path` · kind (`page`,
|
|
13
|
+
`api`, `action`, `job`, `webhook`) · status (`live`, `routable`, `off` — kernel § Context docs).
|
|
14
|
+
A module owning no entry point of its own names the ones that reach it; a module no live entry
|
|
15
|
+
point reaches is `dormant`, which is derived, not a fourth status. Updated in the PR that changes
|
|
16
|
+
exposure, verified at `/promote`, and checkable by diffing these paths against the real routes._
|
|
18
17
|
|
|
19
|
-
| Module | Owns | Traces to |
|
|
20
|
-
| --- | --- | --- |
|
|
21
|
-
| <module
|
|
18
|
+
| Module | Owns | Critical | Traces to | Exposure — entry points |
|
|
19
|
+
| --- | --- | --- | --- | --- |
|
|
20
|
+
| <module> | <what it owns, one line> | yes \| no | <user action OR entity cluster> | `app/(app)/<x>/page.tsx` · page · **live**<br>`app/api/<x>/route.ts` · api · **live**<br>`jobs/<x>.ts` · job · **off** |
|
|
21
|
+
| <module> | ... | no | ... | _no entry point of its own — reached by `<module>` (live)_ |
|
|
22
|
+
| <module> | ... | no | ... | _dormant — no live entry point reaches it_ |
|
|
23
|
+
|
|
24
|
+
_This column grades the **product** severity of a finding, never its security severity. Every
|
|
25
|
+
routable entry point is covered by the kernel's security checklist whatever the status says._
|
|
22
26
|
|
|
23
27
|
**Drift challenge answered**
|
|
24
28
|
|
|
25
|
-
_"Does any module
|
|
29
|
+
_"Does any module own something no user ever reaches, or does any user journey cross boundaries
|
|
30
|
+
this map does not support?"_
|
|
26
31
|
|
|
27
32
|
## 2. Agent Orchestration Model
|
|
28
33
|
|
|
29
|
-
_How LLM calls compose
|
|
30
|
-
|
|
31
|
-
**LLM call sites**
|
|
34
|
+
_How the LLM calls compose: which module calls, what comes back, who consumes it, where the prompts
|
|
35
|
+
live. Named call sites, not "the LLM handles it"._
|
|
32
36
|
|
|
33
37
|
| Call site (module.fn) | Trigger | Model | Returns | Downstream consumer |
|
|
34
38
|
| --- | --- | --- | --- | --- |
|
|
35
|
-
| <module>.<function> | <what triggers
|
|
39
|
+
| <module>.<function> | <what triggers it> | <model id> | <schema or one line> | <module> |
|
|
36
40
|
|
|
37
41
|
**Tool boundaries**
|
|
38
42
|
|
|
39
|
-
_Which tools each call site
|
|
43
|
+
_Which tools each call site may invoke, which are out of bounds, and where the kill switch is._
|
|
40
44
|
|
|
41
45
|
**Drift challenge answered**
|
|
42
46
|
|
|
43
|
-
_"Does any LLM call site bypass
|
|
47
|
+
_"Does any LLM call site bypass its declared tool boundaries, or have an unnamed retry or fallback
|
|
48
|
+
path?"_
|
|
44
49
|
|
|
45
50
|
## 3. Deterministic-vs-LLM Split
|
|
46
51
|
|
|
47
|
-
_Per
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
For each flow named in the brief's persona vignettes:
|
|
52
|
+
_Per flow, per step: code or prompt, and why. A flow that genuinely is one model call is one row
|
|
53
|
+
with its schema and its rationale — the rule is against the undeclared boundary, not against short
|
|
54
|
+
tables._
|
|
52
55
|
|
|
53
56
|
### Flow: <flow-name>
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
| Step | Mechanism | Rationale (ties to measurable property) |
|
|
58
|
+
| Step | Mechanism | Rationale (names a property) |
|
|
58
59
|
| --- | --- | --- |
|
|
59
|
-
| 1. <step
|
|
60
|
-
| 2. ... | ... | ... |
|
|
60
|
+
| 1. <step> | deterministic \| llm | <one sentence — determinism \| cost \| latency \| capability> |
|
|
61
61
|
|
|
62
62
|
**Drift challenge answered**
|
|
63
63
|
|
|
64
|
-
_"Does any flow have a step
|
|
64
|
+
_"Does any flow have a step whose mechanism is undeclared, or a rationale tied to no property?"_
|
|
65
65
|
|
|
66
66
|
## 4. State-Ownership Map
|
|
67
67
|
|
|
68
|
-
_Where conversation state
|
|
69
|
-
|
|
70
|
-
**State classes**
|
|
68
|
+
_Where conversation state, workspace state and ephemeral state live. Each names its owning module
|
|
69
|
+
from Section 1 and its persistence layer from `data-architecture.md`._
|
|
71
70
|
|
|
72
71
|
| State class | Owning module | Persistence layer | Lifetime |
|
|
73
72
|
| --- | --- | --- | --- |
|
|
74
|
-
| <e.g
|
|
73
|
+
| <e.g. conversation history> | <module> | <entity OR "ephemeral"> | durable \| session \| request |
|
|
75
74
|
|
|
76
75
|
**Drift challenge answered**
|
|
77
76
|
|
|
@@ -79,24 +78,13 @@ _"Does any state class lack an owning module from Section 1?"_
|
|
|
79
78
|
|
|
80
79
|
## 5. Surface Boundaries
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
**Surface declaration**
|
|
81
|
+
_Which surfaces this application has, and which module carries each. The usual set is `ui`, `api`,
|
|
82
|
+
`agent`, `db`, `auth`, `infra`; add or omit as the product requires._
|
|
85
83
|
|
|
86
|
-
| Surface |
|
|
87
|
-
| --- | --- | --- |
|
|
88
|
-
|
|
|
89
|
-
| api | ... | ... | ... |
|
|
90
|
-
| agent | ... | ... | ... |
|
|
91
|
-
| db | ... | ... | ... |
|
|
92
|
-
| auth | ... | ... | ... |
|
|
93
|
-
| infra | ... | ... | ... |
|
|
94
|
-
| <custom> | ... | ... | ... |
|
|
84
|
+
| Surface | Present? | Modules carrying it |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| <surface> | yes \| no | <modules> |
|
|
95
87
|
|
|
96
88
|
**Drift challenge answered**
|
|
97
89
|
|
|
98
|
-
_"Does any surface
|
|
99
|
-
|
|
100
|
-
## Coherence check (end-of-atom)
|
|
101
|
-
|
|
102
|
-
_When the atom reaches terminal state, the agent re-runs all five drift challenges to ensure section-targeted edits did not silently break other sections. The coherence check is fatal — any unanswered challenge halts the commit._
|
|
90
|
+
_"Does any surface have no module mapped to it?"_
|
|
@@ -1,127 +1,103 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: data-architecture
|
|
3
3
|
type: data-architecture
|
|
4
|
-
|
|
5
|
-
owner: <git-handle>
|
|
6
|
-
assumes-database: postgres # explicit so Phase 4 stack-decide can flag drift
|
|
4
|
+
assumes-database: postgres # explicit, so a database change surfaces as a contradiction
|
|
7
5
|
schema-snapshot-date: <YYYY-MM-DD>
|
|
8
|
-
rag-architecture-version: 1
|
|
9
|
-
derived-from: [product-brief]
|
|
10
|
-
downstream: [app-architecture, threat-model, hardening-checklist, module-spec/*]
|
|
11
|
-
created: <YYYY-MM-DD>
|
|
12
6
|
updated: <YYYY-MM-DD>
|
|
13
|
-
schema-version: 1
|
|
14
7
|
---
|
|
15
8
|
|
|
16
9
|
## 1. Tenancy Model
|
|
17
10
|
|
|
18
|
-
_The load-bearing question.
|
|
11
|
+
_The load-bearing question. Nothing downstream stabilizes until this one is concrete._
|
|
19
12
|
|
|
20
13
|
**A tenant is a ...**
|
|
21
14
|
|
|
22
|
-
_One concrete noun from this product's own vocabulary, plus the rule for who is inside one and who
|
|
15
|
+
_One concrete noun from this product's own vocabulary, plus the rule for who is inside one and who
|
|
16
|
+
is not. Common shapes, offered as examples rather than as a menu: the customer organization (users
|
|
17
|
+
inside share visibility); a sub-team within it; the individual user. Products whose tenant is a
|
|
18
|
+
project, a device, a contract, a site or a case are ordinary and none of those three fit them —
|
|
19
|
+
name yours._
|
|
23
20
|
|
|
24
21
|
**Rationale**
|
|
25
22
|
|
|
26
|
-
_One sentence tying the tenant to a
|
|
23
|
+
_One sentence tying the tenant to a real user. Example: "The tenant is the customer organization,
|
|
24
|
+
because Maya shares visibility with her 6 reps and nobody has asked for sub-team isolation."_
|
|
27
25
|
|
|
28
26
|
**Tenant identifier**
|
|
29
27
|
|
|
30
|
-
_The column name and type
|
|
28
|
+
_The column name and type scoping every tenant-scoped table (`workspace_id uuid`, `org_id text`).
|
|
29
|
+
Every RLS predicate below references this column._
|
|
31
30
|
|
|
32
31
|
## 2. Entity Graph
|
|
33
32
|
|
|
34
|
-
_The
|
|
35
|
-
|
|
36
|
-
**Entities**
|
|
33
|
+
_The entities and their relationships. Each entity traces to something a user does, or to the
|
|
34
|
+
tenancy model above._
|
|
37
35
|
|
|
38
36
|
| Entity | Owns | Traces to | Relationships |
|
|
39
37
|
| --- | --- | --- | --- |
|
|
40
|
-
| <entity-name> | <one-line statement> | <
|
|
38
|
+
| <entity-name> | <one-line statement> | <user action OR tenancy-derived> | <FK refs> |
|
|
41
39
|
|
|
42
|
-
**Conventions**
|
|
40
|
+
**Conventions**
|
|
43
41
|
|
|
44
|
-
_Naming (snake_case, plural tables), timestamps (`created_at`, `updated_at
|
|
42
|
+
_Naming (snake_case, plural tables), timestamps (`created_at`, `updated_at`, ISO 8601), soft- vs
|
|
43
|
+
hard-deletes per entity, UUID vs serial with rationale, audit fields if any._
|
|
45
44
|
|
|
46
45
|
**Drift challenge answered**
|
|
47
46
|
|
|
48
|
-
_"Does any entity here
|
|
47
|
+
_"Does any entity here trace to nothing a user does? Name it."_
|
|
49
48
|
|
|
50
49
|
## 3. RLS Posture
|
|
51
50
|
|
|
52
|
-
|
|
51
|
+
_Every entity from Section 2 falls into one of two categories — there is no third._
|
|
53
52
|
|
|
54
53
|
**Tenant-scoped tables**
|
|
55
54
|
|
|
56
55
|
| Table | Policy predicate sketch | Notes |
|
|
57
56
|
| --- | --- | --- |
|
|
58
|
-
| <table> | `<tenant-column> = current_setting('app.<tenant-column>')::uuid` | <e.g
|
|
57
|
+
| <table> | `<tenant-column> = current_setting('app.<tenant-column>')::uuid` | <e.g. RPC-only writes> |
|
|
59
58
|
|
|
60
59
|
**Intentionally global tables**
|
|
61
60
|
|
|
62
61
|
| Table | Why no RLS | Rationale |
|
|
63
62
|
| --- | --- | --- |
|
|
64
|
-
| <table> | <lookup data \| public reference
|
|
63
|
+
| <table> | <lookup data \| public reference> | <one sentence> |
|
|
65
64
|
|
|
66
65
|
**Drift challenge answered**
|
|
67
66
|
|
|
68
|
-
_"Does any tenant-scoped entity have
|
|
67
|
+
_"Does any tenant-scoped entity have a policy the tenancy model would not enforce? Name it."_
|
|
69
68
|
|
|
70
69
|
## 4. RAG / pgvector
|
|
71
70
|
|
|
72
|
-
_Whether
|
|
73
|
-
|
|
74
|
-
**Use in v1**
|
|
75
|
-
|
|
76
|
-
_`yes` or `not-in-v1`. If not-in-v1, justify in one sentence (e.g., "v1 ships change-awareness without semantic retrieval; pgvector is a v2 layer")._
|
|
77
|
-
|
|
78
|
-
**Embedding-bearing entities**
|
|
71
|
+
_Whether embeddings are in use, what carries them, which model, and the tenant-scoped retrieval
|
|
72
|
+
RPC. If they are not in use, say so in one sentence and skip ahead._
|
|
79
73
|
|
|
80
74
|
| Entity | Embedding column | Model | Dimensions | Tenant-scoped retrieval RPC |
|
|
81
75
|
| --- | --- | --- | --- | --- |
|
|
82
|
-
| <entity> | <column
|
|
83
|
-
|
|
84
|
-
**Tenant-scoping requirement**
|
|
76
|
+
| <entity> | <column> | <e.g. openai:text-embedding-3-small> | <e.g. 1536> | <RPC signature with the tenant predicate> |
|
|
85
77
|
|
|
86
|
-
_Every retrieval RPC
|
|
78
|
+
_Every retrieval RPC filters by the Section 1 tenant identifier, inside the similarity search and
|
|
79
|
+
not after it._
|
|
87
80
|
|
|
88
81
|
**Drift challenge answered**
|
|
89
82
|
|
|
90
|
-
_"Does any embedding-bearing entity have a retrieval
|
|
83
|
+
_"Does any embedding-bearing entity have a retrieval path that bypasses tenant scoping?"_
|
|
91
84
|
|
|
92
85
|
## 5. Migration Sketches
|
|
93
86
|
|
|
94
|
-
_Postgres-dialect
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
m_0001_initial_schema.sql -- Section 2 entities, tables + FKs, no policies yet
|
|
100
|
-
m_0002_rls_policies.sql -- Section 3 policies, applied per tenant-scoped table
|
|
101
|
-
m_0003_pgvector_setup.sql -- Section 4 RPCs and indexes (skip if not-in-v1)
|
|
102
|
-
m_0004_seed_global_data.sql -- Section 3 intentionally-global table seeds (optional)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
**Sketch — m_0001_initial_schema.sql**
|
|
87
|
+
_Postgres-dialect sketches with `-- TODO: confirm` markers. The migration that ships is written by
|
|
88
|
+
the change that needs it; these are intent, not executable. Ordering: schema → RLS → pgvector. Data
|
|
89
|
+
never lands before its policy._
|
|
106
90
|
|
|
107
91
|
```sql
|
|
108
|
-
--
|
|
109
|
-
create extension if not exists "uuid-ossp";
|
|
110
|
-
|
|
111
|
-
-- TODO: confirm column types and FK ON DELETE behaviors per entity
|
|
92
|
+
-- schema
|
|
112
93
|
create table <entity> (
|
|
113
|
-
id uuid primary key default
|
|
94
|
+
id uuid primary key default gen_random_uuid(),
|
|
114
95
|
<tenant-column> uuid not null references <tenant-table>(id) on delete cascade,
|
|
115
|
-
-- entity-specific columns
|
|
116
96
|
created_at timestamptz not null default now(),
|
|
117
97
|
updated_at timestamptz not null default now()
|
|
118
98
|
);
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
**Sketch — m_0002_rls_policies.sql**
|
|
122
99
|
|
|
123
|
-
|
|
124
|
-
-- TODO: confirm session-variable name matches app convention
|
|
100
|
+
-- policy, in the same migration as the table (kernel § Security checklist)
|
|
125
101
|
alter table <entity> enable row level security;
|
|
126
102
|
|
|
127
103
|
create policy <entity>_tenant_isolation on <entity>
|
|
@@ -129,38 +105,11 @@ create policy <entity>_tenant_isolation on <entity>
|
|
|
129
105
|
using (<tenant-column> = current_setting('app.<tenant-column>')::uuid);
|
|
130
106
|
```
|
|
131
107
|
|
|
132
|
-
**
|
|
133
|
-
|
|
134
|
-
```sql
|
|
135
|
-
-- TODO: confirm pgvector version compatible with embedding model dimensions
|
|
136
|
-
create extension if not exists vector;
|
|
137
|
-
|
|
138
|
-
alter table <embedding-bearing-entity>
|
|
139
|
-
add column embedding vector(<dimensions>);
|
|
140
|
-
|
|
141
|
-
create index on <embedding-bearing-entity> using ivfflat (embedding vector_cosine_ops);
|
|
142
|
-
|
|
143
|
-
-- TODO: confirm RPC signature and tenant predicate
|
|
144
|
-
create or replace function nearest_<entity>(query_embedding vector, k int, p_<tenant-column> uuid)
|
|
145
|
-
returns table (id uuid, score float4)
|
|
146
|
-
language sql stable
|
|
147
|
-
as $$
|
|
148
|
-
select id, embedding <=> query_embedding as score
|
|
149
|
-
from <embedding-bearing-entity>
|
|
150
|
-
where <tenant-column> = p_<tenant-column>
|
|
151
|
-
order by score
|
|
152
|
-
limit k;
|
|
153
|
-
$$;
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Data lifecycle** (subsumed from prior template)
|
|
108
|
+
**Data lifecycle**
|
|
157
109
|
|
|
158
|
-
_Retention
|
|
110
|
+
_Retention per entity, archival path, deletion guarantees (hard-delete, soft-delete, or
|
|
111
|
+
anonymize-and-retain)._
|
|
159
112
|
|
|
160
113
|
**Drift challenge answered**
|
|
161
114
|
|
|
162
|
-
_"Does any migration in
|
|
163
|
-
|
|
164
|
-
## Coherence check (end-of-atom)
|
|
165
|
-
|
|
166
|
-
_When the atom reaches terminal state, the agent re-runs all five drift challenges. Any unanswered challenge halts the commit._
|
|
115
|
+
_"Does any migration in this sequence land data before its policy? Name it."_
|
|
@@ -1,190 +1,96 @@
|
|
|
1
|
-
|
|
2
|
-
id: infrastructure
|
|
3
|
-
type: infrastructure
|
|
4
|
-
status: drafted # drafted | current | needs-refresh | archived
|
|
5
|
-
owner: <git-handle>
|
|
6
|
-
last-quarterly-review: <YYYY-MM-DD>
|
|
7
|
-
created: <YYYY-MM-DD>
|
|
8
|
-
updated: <YYYY-MM-DD>
|
|
9
|
-
schema-version: 1
|
|
10
|
-
---
|
|
1
|
+
_Where things run, why the couplings are what they are, and the traps. Operational truth, not policy — read it before touching env, deploy or dependencies (kernel § Context docs), and update it in the PR that makes it wrong. An honest "we don't have this yet" is the right answer whenever it is the true one._
|
|
11
2
|
|
|
12
|
-
|
|
3
|
+
## Where things run
|
|
13
4
|
|
|
14
|
-
|
|
5
|
+
_One row per distinct runtime — app, edge functions, workers, cron, queue consumers. Names copied from the provider console, not paraphrased._
|
|
15
6
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| Runtime | Provider | Region(s) | Tier / Plan | Notes |
|
|
7
|
+
| Runtime | Provider | Region(s) | Plan / tier | Notes |
|
|
19
8
|
|---|---|---|---|---|
|
|
20
9
|
| | | | | |
|
|
21
10
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
_DNS provider and zone, custom domains, TLS/SSL provisioning, CDN / edge cache, load balancing, ingress rules. Note which records are managed in code (IaC) vs the provider console._
|
|
25
|
-
|
|
26
|
-
- **DNS provider.**
|
|
27
|
-
- **Domains in use.**
|
|
28
|
-
- **TLS provisioning.**
|
|
29
|
-
- **CDN / edge.**
|
|
30
|
-
- **Load balancing.**
|
|
31
|
-
- **Egress controls.**
|
|
11
|
+
- **Domains, DNS, TLS, CDN.**
|
|
12
|
+
- **Declared in code vs clicked in a console.** List the clicked resources explicitly — each one is a load-bearing piece of tribal knowledge.
|
|
32
13
|
|
|
33
|
-
## Data
|
|
14
|
+
## Data & storage
|
|
34
15
|
|
|
35
|
-
|
|
16
|
+
_Operational only. Schema, tenancy and RLS live in `data-architecture.md`._
|
|
36
17
|
|
|
37
|
-
- **Primary database
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **Point-in-time recovery.**
|
|
18
|
+
- **Primary database** — host, plan, connection pooling.
|
|
19
|
+
- **Backups** — cadence, retention, point-in-time-recovery window.
|
|
20
|
+
- **Last restore drill** — date, and what it proved. An untested backup is a wish.
|
|
41
21
|
- **Replicas / failover.**
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
44
|
-
|
|
45
|
-
## Storage
|
|
46
|
-
|
|
47
|
-
_Object storage, file uploads, presigned-URL flows, lifecycle and retention. One row per bucket / container._
|
|
48
|
-
|
|
49
|
-
| Bucket | Provider | Purpose | Public? | Lifecycle | Notes |
|
|
50
|
-
|---|---|---|---|---|---|
|
|
51
|
-
| | | | | | |
|
|
52
|
-
|
|
53
|
-
## Secrets & Configuration
|
|
54
|
-
|
|
55
|
-
_Where secrets live, how they are injected at runtime, rotation cadence, who has access. **The runbook for rotation lives in `incident-runbook.md`; this section names the system, not the steps.**_
|
|
56
|
-
|
|
57
|
-
- **Secret store.**
|
|
58
|
-
- **Injection mechanism.**
|
|
59
|
-
- **Rotation cadence.**
|
|
60
|
-
- **Access control.**
|
|
61
|
-
- **Audit trail.**
|
|
62
|
-
|
|
63
|
-
## Environment Separation
|
|
64
|
-
|
|
65
|
-
_What dev, staging (if present), and production look like, and what differs between them. Data-promotion rules (does prod data ever flow downstream? if so, with what redaction?). Connection-string isolation. **Test-against-prod is a kernel-level forbidden tool; flag any violation here as tech-debt.**_
|
|
66
|
-
|
|
67
|
-
- **Dev.**
|
|
68
|
-
- **Staging.**
|
|
69
|
-
- **Production.**
|
|
70
|
-
- **Data-promotion rules.**
|
|
71
|
-
- **Cross-environment guardrails.**
|
|
72
|
-
|
|
73
|
-
## IaC Inventory
|
|
74
|
-
|
|
75
|
-
_What infrastructure is declared in code vs configured by click in a console. Path to IaC files. Tool (Terraform, Pulumi, CDK, OpenTofu, Supabase migrations, GitHub Actions YAML, Dockerfile). Who can apply. **Click-configured infra is not forbidden, but every clicked resource is a load-bearing tribal-knowledge item; list each one explicitly so it can be promoted to IaC over time.**_
|
|
76
|
-
|
|
77
|
-
| Resource | Source-of-truth | Path / location | Applier(s) | Notes |
|
|
78
|
-
|---|---|---|---|---|
|
|
79
|
-
| | | | | |
|
|
80
|
-
|
|
81
|
-
## Deploy Pipeline
|
|
82
|
-
|
|
83
|
-
_How code reaches each environment. References `ci-cd.md` for the build pipeline; this section captures the deploy half — promotion mechanics, rollout strategy (instant cutover, canary, blue/green), rollback procedure, who can trigger a deploy._
|
|
84
|
-
|
|
85
|
-
- **Build → deploy handoff.**
|
|
86
|
-
- **Promotion path.**
|
|
87
|
-
- **Rollout strategy.**
|
|
88
|
-
- **Rollback procedure.**
|
|
89
|
-
- **Deploy authorization.**
|
|
90
|
-
|
|
91
|
-
## Observability
|
|
22
|
+
- **Vector or search infrastructure.**
|
|
23
|
+
- **Buckets** — one line each: purpose, public or not, lifecycle.
|
|
92
24
|
|
|
93
|
-
|
|
25
|
+
## Environments
|
|
94
26
|
|
|
95
|
-
|
|
96
|
-
- **Metrics.**
|
|
97
|
-
- **Traces.**
|
|
98
|
-
- **Error tracking.**
|
|
99
|
-
- **Uptime monitoring.**
|
|
100
|
-
- **Alert routing.**
|
|
101
|
-
|
|
102
|
-
## Cost & Capacity
|
|
103
|
-
|
|
104
|
-
_Current monthly spend per service (approximate is fine). Budget alerts. Scaling triggers and ceilings. Rate-limiting posture (per-route, per-tenant). **Cost is a security and reliability concern, not just a finance concern: an unbounded scale ceiling is a billing-DoS vector.**_
|
|
27
|
+
_What dev, preview and production are, and what actually differs between them._
|
|
105
28
|
|
|
106
|
-
|
|
|
29
|
+
| Environment | App URL | Database it points at | Seed data | Notes |
|
|
107
30
|
|---|---|---|---|---|
|
|
108
31
|
| | | | | |
|
|
109
32
|
|
|
110
|
-
- **
|
|
111
|
-
- **
|
|
33
|
+
- **Source of truth for environment variables**, and how they are scoped per environment.
|
|
34
|
+
- **Does production data ever flow downstream?** If so, with what redaction.
|
|
35
|
+
- **Cross-environment guardrails.** Testing against production is a kernel-forbidden path; a violation found here is a tech-debt file, not a footnote.
|
|
112
36
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
_Recovery Point Objective (RPO) and Recovery Time Objective (RTO) targets per critical resource. Backup restore procedure (high level — full steps live in `incident-runbook.md`). Drill cadence — when was the last successful restore test, and when is the next scheduled. **An untested backup is a wish, not a recovery plan.**_
|
|
116
|
-
|
|
117
|
-
| Resource | RPO target | RTO target | Last drill | Next drill |
|
|
118
|
-
|---|---|---|---|---|
|
|
119
|
-
| | | | | |
|
|
37
|
+
## Secrets
|
|
120
38
|
|
|
121
|
-
|
|
39
|
+
- **Where they live.** The one store that is authoritative.
|
|
40
|
+
- **How they reach the runtime.**
|
|
41
|
+
- **Who has access**, and how that is reviewed.
|
|
42
|
+
- **Rotation** — cadence, and where the steps are written down.
|
|
122
43
|
|
|
123
|
-
|
|
44
|
+
## Deploy Pipeline
|
|
124
45
|
|
|
125
|
-
|
|
126
|
-
|---|---|---|---|---|
|
|
127
|
-
| | | | | |
|
|
46
|
+
_How code reaches production, and the exact commands `/hstack-promote` will look for here. A command left blank halts the promotion — which is the correct outcome, because guessing a production command is how the wrong project gets migrated._
|
|
128
47
|
|
|
129
|
-
|
|
48
|
+
| What `/hstack-promote` needs | Command |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Apply a pending migration to production | |
|
|
51
|
+
| List deployments and their state | |
|
|
52
|
+
| Smoke-test a specific deployment URL | |
|
|
53
|
+
| Read production logs | |
|
|
54
|
+
| Promote a deployment | |
|
|
55
|
+
| Roll back to the previous deployment | |
|
|
130
56
|
|
|
131
|
-
|
|
57
|
+
- **Promotion path.** How a merge becomes an unpromoted production build, and what promotes it. Auto-assignment of the production domain must be off for the staged flow to exist at all.
|
|
58
|
+
- **Who may promote.**
|
|
59
|
+
- **Rollback.** What re-promoting the previous deployment does and does not undo — migrations are additive, so they stay.
|
|
132
60
|
|
|
133
|
-
|
|
134
|
-
|---|---|---|---|---|
|
|
135
|
-
| | | | | |
|
|
61
|
+
## Observability
|
|
136
62
|
|
|
137
|
-
-
|
|
138
|
-
- **Audit log retention.**
|
|
139
|
-
- **Access review cadence.**
|
|
63
|
+
_Where `/hstack-promote` looks in its post-promotion window, and where a daily glance happens._
|
|
140
64
|
|
|
141
|
-
|
|
65
|
+
- **Logs** — where, retention.
|
|
66
|
+
- **Error tracking** — tool, project, who watches it.
|
|
67
|
+
- **Uptime monitoring.**
|
|
68
|
+
- **Alert routing** — which alert reaches whom, on which channel. "Nobody is paged" is an answer; write it down rather than implying one.
|
|
142
69
|
|
|
143
|
-
|
|
70
|
+
## Couplings & gotchas
|
|
144
71
|
|
|
145
|
-
|
|
146
|
-
|---|---|---|---|---|---|---|
|
|
147
|
-
| | | | | | | |
|
|
72
|
+
_The section that earns this file. Everything a newcomer — human or agent — would otherwise learn by breaking production: a region that must match another region, a version pinned because the next one broke us, a service that must be deployed before another, a quota that bites at a specific hour._
|
|
148
73
|
|
|
149
|
-
|
|
74
|
+
-
|
|
150
75
|
|
|
151
|
-
|
|
76
|
+
_External services this depends on at runtime. Criticality: `hard` = the product is down, `soft` = degraded, `optional` = no user impact._
|
|
152
77
|
|
|
153
|
-
|
|
|
78
|
+
| Provider | Purpose | Criticality | What happens when it is down |
|
|
154
79
|
|---|---|---|---|
|
|
155
80
|
| | | | |
|
|
156
81
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
- **Supabase MCP.** Dev project, staging project, production project — each on its own row. "Not wired" is an acceptable and often preferred value, especially for production.
|
|
160
|
-
- **Other MCPs** (Notion, GitHub, Linear, Figma, Slack, etc.). Each with its own access scope, token location, rotation. Notion and Slack MCPs in particular often surface external user-generated content into the session — flag them explicitly under INF-05.
|
|
161
|
-
|
|
162
|
-
## Compliance & Data Residency
|
|
163
|
-
|
|
164
|
-
_Regions where customer data lives at rest. GDPR-relevant flows (subject-access, deletion, export). Encryption at rest and in transit per data class. SOC 2 readiness gaps (this is honest enumeration, not a claim of posture). **v1 hstack does not by itself deliver SOC 2 or GDPR posture; the kernel says so explicitly. This section catalogs the gap, it does not close it.**_
|
|
82
|
+
## MCP access
|
|
165
83
|
|
|
166
|
-
-
|
|
167
|
-
- **GDPR flows.**
|
|
168
|
-
- **Encryption at rest.**
|
|
169
|
-
- **Encryption in transit.**
|
|
170
|
-
- **Known compliance gaps.**
|
|
84
|
+
_Which MCP servers are wired, where they point, what they can do. An MCP is a security boundary equivalent to the token it carries: a session with a project-scoped token has that project's full blast radius. The rules — no write-capable MCP against production outside `/hstack-promote`, and no write-capable MCP active in a session that reads user-generated tenant-scoped content — belong to the kernel § Stop conditions. This table is the inventory those rules are applied to._
|
|
171
85
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
_External SaaS the system depends on at runtime. One row per provider. Criticality reflects what happens if the provider is unavailable: `hard` = product is down, `soft` = degraded, `optional` = no user impact._
|
|
175
|
-
|
|
176
|
-
| Provider | Purpose | Criticality | Contractual SLO | Failure-mode behavior |
|
|
86
|
+
| MCP server | Points at | Access mode | Token storage | Notes |
|
|
177
87
|
|---|---|---|---|---|
|
|
178
88
|
| | | | | |
|
|
179
89
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
_Open tech-debt items pointing to infrastructure shortcomings. Each entry is a link to a `hstack/tech-debt/TD-NNNN-<slug>.md` file. This section is the bridge between the operational truth captured above and the workflow's tech-debt machinery — every honest gap surfaced during the interview should land as a TD via `/hstack:tech-debt-new --origin <change-id>`._
|
|
183
|
-
|
|
184
|
-
-
|
|
90
|
+
_"Not wired" is an acceptable value, and often the preferred one for production._
|
|
185
91
|
|
|
186
|
-
##
|
|
92
|
+
## Known gaps
|
|
187
93
|
|
|
188
|
-
|
|
94
|
+
_What is missing or unknown, named rather than implied. A gap with a shape is a file under `hstack/tech-debt/`; link it here. A gap without one — a dependency whose failure mode nobody has thought through — is a line here until someone does._
|
|
189
95
|
|
|
190
96
|
-
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
type: roadmap
|
|
4
|
-
status: drafted # drafted | current | needs-refresh | archived
|
|
5
|
-
owner: <git-handle>
|
|
6
|
-
source: local # local | rhizome — who owns the truth; when rhizome, local edits are refused and the sync is authoritative
|
|
7
|
-
reviewed-on: <YYYY-MM-DD> # planner treats the roadmap as stale beyond 90 days
|
|
8
|
-
created: <YYYY-MM-DD>
|
|
9
|
-
updated: <YYYY-MM-DD>
|
|
10
|
-
schema-version: 1
|
|
2
|
+
reviewed-on: <YYYY-MM-DD> # past 90 days, treat this roadmap as stale rather than current
|
|
11
3
|
---
|
|
12
4
|
|
|
5
|
+
_Advisory only, never a gate (kernel § Context docs). It informs one-way-door decisions and the Forecloses / Enables section of an ADR; it never decides whether a change ships._
|
|
6
|
+
|
|
13
7
|
## Now
|
|
14
8
|
|
|
15
|
-
_What we are committed to shipping.
|
|
9
|
+
_What we are committed to shipping. Each item: one product line, one architectural-implication line. Vague fortune-telling ("might need to scale") is worse than absence._
|
|
16
10
|
|
|
17
11
|
- <item> — **architectural implication:** <one line>
|
|
18
12
|
|
|
@@ -30,12 +24,12 @@ _Plausible futures. These influence one-way-door decisions ONLY — never day-to
|
|
|
30
24
|
|
|
31
25
|
## Not on the path
|
|
32
26
|
|
|
33
|
-
_Explicit renouncements, with the reason.
|
|
27
|
+
_Explicit renouncements, with the reason._
|
|
34
28
|
|
|
35
29
|
- <item> — <why not>
|
|
36
30
|
|
|
37
31
|
## Success criteria for the current horizon
|
|
38
32
|
|
|
39
|
-
_Concrete observable indicators that Now is done and Next gets promoted.
|
|
33
|
+
_Concrete observable indicators that Now is done and Next gets promoted._
|
|
40
34
|
|
|
41
35
|
-
|