Compare commits
+11
-2
@@ -1,6 +1,10 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
|
"Skill(pql)",
|
||||||
|
"Skill(clide)",
|
||||||
|
"Skill(whats-next)",
|
||||||
|
"Skill(git-commit)",
|
||||||
"Bash(git add *)",
|
"Bash(git add *)",
|
||||||
"Bash(git commit *)",
|
"Bash(git commit *)",
|
||||||
"Bash(git status *)",
|
"Bash(git status *)",
|
||||||
@@ -30,9 +34,11 @@
|
|||||||
"Bash(make *)",
|
"Bash(make *)",
|
||||||
"Bash(pql)",
|
"Bash(pql)",
|
||||||
"Bash(pql *)",
|
"Bash(pql *)",
|
||||||
"Bash(awk *)"
|
"Bash(clide)",
|
||||||
|
"Bash(clide *)"
|
||||||
],
|
],
|
||||||
"deny": [
|
"deny": [
|
||||||
|
"Edit(//var/mnt/data/projects/treesitter/**)",
|
||||||
"Bash(rm -rf /*)",
|
"Bash(rm -rf /*)",
|
||||||
"Bash(rm -rf ~*)",
|
"Bash(rm -rf ~*)",
|
||||||
"Bash(rm -rf $HOME*)",
|
"Bash(rm -rf $HOME*)",
|
||||||
@@ -53,7 +59,10 @@
|
|||||||
"Bash(git checkout -- *)",
|
"Bash(git checkout -- *)",
|
||||||
"Bash(git restore .*)",
|
"Bash(git restore .*)",
|
||||||
"Bash(chmod -R 777 *)",
|
"Bash(chmod -R 777 *)",
|
||||||
"Bash(chmod 777 *)"
|
"Bash(chmod 777 *)",
|
||||||
|
"Bash(git add -A*)",
|
||||||
|
"Bash(git add --all*)",
|
||||||
|
"Bash(git add .)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-10
@@ -5,19 +5,22 @@ lives in its own directory with a `SKILL.md` (frontmatter + body) and any
|
|||||||
helper scripts. This index is for humans skimming what's available; Claude
|
helper scripts. This index is for humans skimming what's available; Claude
|
||||||
discovers skills automatically from the directory structure.
|
discovers skills automatically from the directory structure.
|
||||||
|
|
||||||
|
Only clide-specific skills live in this repo. Repo-agnostic skills
|
||||||
|
(`d2-diagram`, `frame0-wireframe`, `skill-create`) live at user scope
|
||||||
|
(`~/.claude/skills/`), as do the pql-distributed ones (`pql`, `clean-house`,
|
||||||
|
installed via `pql init`).
|
||||||
|
|
||||||
| Skill | Purpose |
|
| Skill | Purpose |
|
||||||
|---|---|
|
|---|---|
|
||||||
| [`d2-diagram`](d2-diagram/SKILL.md) | Generate technical diagrams from `.d2` source with the d2 CLI; renders to PNG. |
|
| [`clide`](clide/SKILL.md) | Observe/drive the live clide UI through the `clide` CLI; discover the surface with `clide capabilities`. |
|
||||||
| [`frame0-wireframe`](frame0-wireframe/SKILL.md) | Author UI wireframes as local JSON and sync to the Frame0 desktop app for rendering + export. |
|
| [`git-commit`](git-commit/SKILL.md) | Commit conventions for this repo — message style, CHANGELOG discipline (60-word cap), attribution trailer, safety rules. |
|
||||||
| [`git-commit`](git-commit/SKILL.md) | Commit conventions for this repo — message style, CHANGELOG discipline (40/60 word cap), attribution trailer, safety rules. |
|
| [`testmode`](testmode/SKILL.md) | Run and interpret the `ClideTestApp` platform integration harness; smoke-test after toolchain / IPC / PTY / theme / native changes. |
|
||||||
| [`pql`](pql/SKILL.md) | Query and plan against the markdown vault via the `pql` CLI (decisions, tickets, structural queries). |
|
| [`ui-design`](ui-design/SKILL.md) | Visual design guide — surface tokens, control geometry, Phosphor icons (`byName` + generated glyph table). |
|
||||||
| [`skill-create`](skill-create/SKILL.md) | Guidance for creating new skills — SKILL.md structure, bundling scripts, packaging. |
|
|
||||||
| [`testmode`](testmode/SKILL.md) | Run and interpret the `ClideTestApp` platform integration harness; smoke-test after toolchain / IPC / theme / native changes. |
|
|
||||||
| [`ui-design`](ui-design/SKILL.md) | Visual design guide — surface tokens, control geometry, Phosphor icons. |
|
|
||||||
| [`whats-next`](whats-next/SKILL.md) | Dependency-driven batch selection against the pql backlog. Walks the initiative/epic tree, filters unblocked work, refines, optionally activates. |
|
| [`whats-next`](whats-next/SKILL.md) | Dependency-driven batch selection against the pql backlog. Walks the initiative/epic tree, filters unblocked work, refines, optionally activates. |
|
||||||
|
|
||||||
## Adding a skill
|
## Adding a skill
|
||||||
|
|
||||||
Use the `skill-create` skill (or follow its SKILL.md by hand). Add a row to
|
Use the `skill-create` skill (user scope; or follow its SKILL.md by hand).
|
||||||
the table above so the inventory stays accurate; the index is otherwise just
|
Clide-specific skills go here; repo-agnostic ones go to `~/.claude/skills/`.
|
||||||
a directory listing.
|
Add a row to the table above so the inventory stays accurate; the index is
|
||||||
|
otherwise just a directory listing.
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
name: clide
|
||||||
|
description: >
|
||||||
|
clide is the IDE hosting this session; it puts `clide` on your PATH and a
|
||||||
|
per-workspace socket in `CLIDE_SOCK`. Start with `clide capabilities` to
|
||||||
|
enumerate the live tool surface, then observe or drive the UI — panes,
|
||||||
|
editor, files, git, readers, toasts, layout — via `clide <subsystem> <verb>`.
|
||||||
|
Triggers: "what can clide do", "drive the clide UI", "open this in clide",
|
||||||
|
"show the user", "toast", or invoking /clide.
|
||||||
|
user-invocable: true
|
||||||
|
allowed-tools: Bash
|
||||||
|
---
|
||||||
|
|
||||||
|
# Driving clide from the CLI
|
||||||
|
|
||||||
|
You are (often) running **inside clide** — a Flutter IDE that hosts this
|
||||||
|
Claude session. It puts `clide` on your PATH and exposes its whole UI surface
|
||||||
|
as a `clide <subsystem> <verb>` CLI, talking to the running app over a
|
||||||
|
per-workspace socket (`CLIDE_SOCK`). Every UI action the user can take has a
|
||||||
|
CLI verb, and every
|
||||||
|
verb's effect is observable — that is the parity contract (D-6). So you can
|
||||||
|
*see what the user sees* and *show the user what you mean*.
|
||||||
|
|
||||||
|
## Discover the surface first — don't hard-code it
|
||||||
|
|
||||||
|
The authoritative, always-current list of commands is the app itself:
|
||||||
|
|
||||||
|
```
|
||||||
|
clide capabilities
|
||||||
|
```
|
||||||
|
|
||||||
|
It returns JSON: every registered command, split into `subsystem` + `verb`,
|
||||||
|
with its argument schema (`positional` order + per-arg `type`/`required`/
|
||||||
|
constraints) where one is declared. **Sourced from the live dispatcher
|
||||||
|
registry, so it never drifts.** New panels/verbs appear here the moment they
|
||||||
|
register — re-run it instead of trusting a remembered list (including this
|
||||||
|
one). `clide <subsystem>` with no verb, or an unknown command, prints usage.
|
||||||
|
|
||||||
|
## The two halves of parity
|
||||||
|
|
||||||
|
- **Observe** — read the live UI state:
|
||||||
|
- `clide status` — one-shot orientation: workspace, git, active editor
|
||||||
|
buffer + selection, open reader docs, the panes the user sees, layout.
|
||||||
|
- `clide pane list`, `clide editor active` — narrower snapshots.
|
||||||
|
- **Drive** — make the UI do something:
|
||||||
|
- `clide ui open <reader> <ref>` — open a doc in a GUI reader
|
||||||
|
(`tickets`/`decisions` by id, `markdown`/`diff` by path): "look at this
|
||||||
|
with me." `diff <path>` reveals the diff tab and scrolls to that file.
|
||||||
|
- `clide ui toast "message" [--severity success|warning|error|info]` — raise
|
||||||
|
a toast on the user's screen: "tests green", "push failed".
|
||||||
|
- pane/editor/files/git verbs — see `clide capabilities` for the current set
|
||||||
|
and their args.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- **Slots:** the layout has four content slots — `sidebar` (left), `workspace`
|
||||||
|
(center, where Claude lives), `context` (right), and `dock` (bottom —
|
||||||
|
Output/Problems panes, hidden by default; D-87) — plus the bottom
|
||||||
|
`statusbar`. Many verbs take a slot. The live list is whatever
|
||||||
|
`clide capabilities` reports.
|
||||||
|
- **Honest failures:** a drive verb with no live GUI returns a `toolError`
|
||||||
|
("no live UI to drive"), not a hang. JSON on stdout; exit code conveys
|
||||||
|
ok/usage/tool error.
|
||||||
|
- **You only see what flows through clide.** Your own non-`clide` shell work
|
||||||
|
(plain file reads, `make test`, `git`) is outside clide's view by design
|
||||||
|
(D-83) — run it *through* `clide …` if you want clide to observe it.
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
---
|
|
||||||
name: d2-diagram
|
|
||||||
description: >
|
|
||||||
Generate technical diagrams using d2 (text-to-diagram CLI). Use when the
|
|
||||||
user says "create a diagram", "draw architecture", "make a flowchart",
|
|
||||||
"diagram this", "render d2", "d2", "data flow diagram", "entity relationship",
|
|
||||||
"state machine", "sequence diagram", "UI flow", or invokes /d2-diagram.
|
|
||||||
Produces .d2 source files and renders them to PNG. Also use when asked
|
|
||||||
to update, re-render, or batch render existing diagrams.
|
|
||||||
---
|
|
||||||
|
|
||||||
# d2 Diagram Generation
|
|
||||||
|
|
||||||
Generate technical diagrams from text using d2 (v0.7.1). Pure CLI, no
|
|
||||||
external dependencies beyond the d2 binary.
|
|
||||||
|
|
||||||
**Binary:** `/home/linuxbrew/.linuxbrew/bin/d2`
|
|
||||||
|
|
||||||
## Project Defaults
|
|
||||||
|
|
||||||
| Setting | Value | Override |
|
|
||||||
|---------|-------|----------|
|
|
||||||
| Theme | 200 (Dark Mauve) | `--theme N` |
|
|
||||||
| Layout | dagre | `--layout elk` |
|
|
||||||
| Padding | 100px | — |
|
|
||||||
| Format | PNG | `--svg` |
|
|
||||||
|
|
||||||
## Output Convention
|
|
||||||
|
|
||||||
```
|
|
||||||
docs/diagrams/
|
|
||||||
architecture/ # System architecture, IPC, component layout
|
|
||||||
data-flow/ # Sequence diagrams, data pipelines
|
|
||||||
entity/ # ER diagrams, ECS component schemas
|
|
||||||
state/ # State machines, behavior trees
|
|
||||||
ui/ # UI navigation flow, screen transitions
|
|
||||||
```
|
|
||||||
|
|
||||||
Both `.d2` source and `.png` output are tracked in git.
|
|
||||||
|
|
||||||
## Single Diagram Workflow
|
|
||||||
|
|
||||||
1. **Determine category** — architecture, data-flow, entity, state, or ui
|
|
||||||
2. **Read template** — `references/diagram-templates.md` for the matching category
|
|
||||||
3. **Read syntax** — `references/d2-syntax-guide.md` if unfamiliar with d2 syntax
|
|
||||||
4. **Write .d2 source** — to `docs/diagrams/{category}/{name}.d2`
|
|
||||||
5. **Validate** — `.claude/skills/d2-diagram/scripts/d2-render.sh validate {file}`
|
|
||||||
6. **Render** — `.claude/skills/d2-diagram/scripts/d2-render.sh {file}`
|
|
||||||
7. **Read SVG** — verify the output, present to user
|
|
||||||
|
|
||||||
### Script Usage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Render with project defaults
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh docs/diagrams/architecture/ipc-bridge.d2
|
|
||||||
|
|
||||||
# Validate syntax only
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh validate docs/diagrams/architecture/ipc-bridge.d2
|
|
||||||
|
|
||||||
# Auto-format source
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh fmt docs/diagrams/architecture/ipc-bridge.d2
|
|
||||||
|
|
||||||
# Sketch mode (hand-drawn look for drafts)
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh docs/diagrams/ui/flow.d2 --sketch
|
|
||||||
|
|
||||||
# Light theme (for printable docs)
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh docs/diagrams/entity/schema.d2 --theme 0
|
|
||||||
|
|
||||||
# SVG output (if specifically needed)
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-render.sh docs/diagrams/architecture/overview.d2 --svg
|
|
||||||
```
|
|
||||||
|
|
||||||
## Batch Render
|
|
||||||
|
|
||||||
Re-render all diagrams after theme or style changes:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# All diagrams
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-batch.sh
|
|
||||||
|
|
||||||
# One category
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-batch.sh docs/diagrams/architecture/
|
|
||||||
|
|
||||||
# Preview what would render
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-batch.sh --dry-run
|
|
||||||
|
|
||||||
# Force re-render everything
|
|
||||||
.claude/skills/d2-diagram/scripts/d2-batch.sh --force
|
|
||||||
```
|
|
||||||
|
|
||||||
Batch skips files whose PNG is newer than the `.d2` source unless `--force`.
|
|
||||||
|
|
||||||
## Advanced Patterns
|
|
||||||
|
|
||||||
### Variables for consistent styling
|
|
||||||
|
|
||||||
```d2
|
|
||||||
vars: {
|
|
||||||
color-bg: "#2a3040"
|
|
||||||
color-stroke: "#333340"
|
|
||||||
color-text: "#c8d0e0"
|
|
||||||
color-accent: "#c8d8f0"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Multi-board (layers)
|
|
||||||
|
|
||||||
```d2
|
|
||||||
# Base diagram here
|
|
||||||
|
|
||||||
layers: {
|
|
||||||
detailed: {
|
|
||||||
# More detailed view
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sequence diagrams
|
|
||||||
|
|
||||||
```d2
|
|
||||||
shape: sequence_diagram
|
|
||||||
client: Godot Client
|
|
||||||
server: Rust Server
|
|
||||||
|
|
||||||
client -> server: TickRequest(delta)
|
|
||||||
server -> client: WorldState(entities)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Imports
|
|
||||||
|
|
||||||
Split shared definitions into a separate file and import:
|
|
||||||
|
|
||||||
```d2
|
|
||||||
...@shared-defs.d2
|
|
||||||
```
|
|
||||||
|
|
||||||
## Agent Guidance
|
|
||||||
|
|
||||||
- **Qatux** — Architecture decision records, system overview diagrams, data
|
|
||||||
schemas. Prefer architecture and entity templates.
|
|
||||||
- **Tyre** — IPC bridge, ECS system flow, chunk loading pipeline, perception
|
|
||||||
system data flow. Prefer architecture and data-flow templates.
|
|
||||||
- **Araminta** — UI navigation flow, screen transitions, component hierarchy.
|
|
||||||
Prefer UI flow template.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- `references/d2-syntax-guide.md` — Language quick reference (shapes, edges,
|
|
||||||
containers, styling, variables). Read when unfamiliar with d2 syntax.
|
|
||||||
- `references/diagram-templates.md` — Five category templates with complete
|
|
||||||
d2 source examples. Read when starting a new diagram.
|
|
||||||
@@ -1,212 +0,0 @@
|
|||||||
# D2 Language Quick Reference
|
|
||||||
|
|
||||||
## Nodes
|
|
||||||
|
|
||||||
```d2
|
|
||||||
server # Implicit label from key
|
|
||||||
server: Simulation Server # Explicit label
|
|
||||||
server: Simulation Server { # With properties
|
|
||||||
shape: hexagon
|
|
||||||
style.fill: "#2d3436"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Edges
|
|
||||||
|
|
||||||
```d2
|
|
||||||
a -> b # Directed
|
|
||||||
a <- b # Reverse directed
|
|
||||||
a <-> b # Bidirectional
|
|
||||||
a -- b # Undirected
|
|
||||||
a -> b: "label" # Labeled edge
|
|
||||||
a -> b -> c # Chained
|
|
||||||
```
|
|
||||||
|
|
||||||
## Containers (nesting)
|
|
||||||
|
|
||||||
```d2
|
|
||||||
infrastructure: {
|
|
||||||
server: Simulation Server
|
|
||||||
database: State Store {
|
|
||||||
shape: cylinder
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Shapes
|
|
||||||
|
|
||||||
| Shape | Use for |
|
|
||||||
|-------|---------|
|
|
||||||
| `rectangle` | Default. Components, modules, generic. |
|
|
||||||
| `hexagon` | Systems, services, major components. |
|
|
||||||
| `cylinder` | Databases, storage, persistent state. |
|
|
||||||
| `diamond` | Decisions, conditions, branch points. |
|
|
||||||
| `oval` / `circle` | Start/end states, events. |
|
|
||||||
| `cloud` | External systems, networks. |
|
|
||||||
| `person` | Actors, users, NPCs. |
|
|
||||||
| `queue` | Message queues, buffers. |
|
|
||||||
| `page` | Documents, files. |
|
|
||||||
| `package` | Packages, modules, crates. |
|
|
||||||
| `sql_table` | Database tables, ECS component schemas. |
|
|
||||||
| `class` | Class diagrams, ECS system definitions. |
|
|
||||||
| `code` | Code blocks (set `language` property). |
|
|
||||||
| `markdown` | Rich text blocks. |
|
|
||||||
|
|
||||||
## SQL Tables
|
|
||||||
|
|
||||||
```d2
|
|
||||||
entity: {
|
|
||||||
shape: sql_table
|
|
||||||
id: u64 {constraint: primary_key}
|
|
||||||
name: String
|
|
||||||
position: Vec2
|
|
||||||
faction_id: u64 {constraint: foreign_key}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Class Diagrams
|
|
||||||
|
|
||||||
```d2
|
|
||||||
perception_system: {
|
|
||||||
shape: class
|
|
||||||
+run(world: &mut World)
|
|
||||||
-calculate_los(entity: Entity): HashSet<Entity>
|
|
||||||
#update_knowledge(entity: Entity, seen: HashSet<Entity>)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sequence Diagrams
|
|
||||||
|
|
||||||
```d2
|
|
||||||
shape: sequence_diagram
|
|
||||||
client: Godot Client
|
|
||||||
server: Rust Server
|
|
||||||
|
|
||||||
client -> server: TickRequest(delta)
|
|
||||||
server -> server: run ECS systems
|
|
||||||
server -> client: WorldState(entities)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Styling
|
|
||||||
|
|
||||||
```d2
|
|
||||||
node: Label {
|
|
||||||
style: {
|
|
||||||
fill: "#2d3436"
|
|
||||||
stroke: "#333340"
|
|
||||||
stroke-width: 2
|
|
||||||
stroke-dash: 5 # Dashed line
|
|
||||||
opacity: 0.8
|
|
||||||
font-size: 14
|
|
||||||
font-color: "#c8d0e0"
|
|
||||||
bold: true
|
|
||||||
italic: false
|
|
||||||
border-radius: 4
|
|
||||||
shadow: true
|
|
||||||
3d: true # Rectangles only
|
|
||||||
multiple: true # Stacked appearance
|
|
||||||
double-border: true # Rectangles/ovals only
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Edge styling
|
|
||||||
|
|
||||||
```d2
|
|
||||||
a -> b: {
|
|
||||||
style: {
|
|
||||||
stroke: "#c8d8f0"
|
|
||||||
stroke-width: 2
|
|
||||||
stroke-dash: 5
|
|
||||||
opacity: 0.8
|
|
||||||
animated: true # Animated flow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Variables
|
|
||||||
|
|
||||||
```d2
|
|
||||||
vars: {
|
|
||||||
color-bg: "#1a1e24"
|
|
||||||
color-stroke: "#333340"
|
|
||||||
color-text: "#c8d0e0"
|
|
||||||
color-accent: "#c8d8f0"
|
|
||||||
}
|
|
||||||
|
|
||||||
node: {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.stroke: ${color-stroke}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Direction
|
|
||||||
|
|
||||||
```d2
|
|
||||||
direction: right # left-to-right (default for dagre)
|
|
||||||
direction: down # top-to-bottom
|
|
||||||
direction: up
|
|
||||||
direction: left
|
|
||||||
```
|
|
||||||
|
|
||||||
## Imports
|
|
||||||
|
|
||||||
```d2
|
|
||||||
...@shared-defs.d2 # Spread import (inline all definitions)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Icons
|
|
||||||
|
|
||||||
```d2
|
|
||||||
node: Label {
|
|
||||||
icon: https://icons.terrastruct.com/essentials/time.svg
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Layers (multi-board)
|
|
||||||
|
|
||||||
```d2
|
|
||||||
# Base diagram content here
|
|
||||||
|
|
||||||
layers: {
|
|
||||||
detailed: {
|
|
||||||
# More detailed view
|
|
||||||
}
|
|
||||||
simplified: {
|
|
||||||
# Simplified overview
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Scenarios (animated transitions)
|
|
||||||
|
|
||||||
```d2
|
|
||||||
# Base state
|
|
||||||
|
|
||||||
scenarios: {
|
|
||||||
alert: {
|
|
||||||
# Changes from base for alert state
|
|
||||||
}
|
|
||||||
combat: {
|
|
||||||
# Changes from base for combat state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Comments
|
|
||||||
|
|
||||||
```d2
|
|
||||||
# This is a comment
|
|
||||||
node: Label # Inline comment
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project Colors (from visual-grammar-v01.md)
|
|
||||||
|
|
||||||
| Constant | Hex | Usage |
|
|
||||||
|----------|-----|-------|
|
|
||||||
| Zone 1 floor | `#1a1e24` | Dark backgrounds |
|
|
||||||
| Zone 1 wall | `#2a3040` | Component fill |
|
|
||||||
| Outline standard | `#333340` | Borders, strokes |
|
|
||||||
| Insert chrome | `#c8d0e0` | Text, labels |
|
|
||||||
| Zone 1 fixture | `#c8d8f0` | Accents, highlights |
|
|
||||||
@@ -1,251 +0,0 @@
|
|||||||
# Diagram Templates
|
|
||||||
|
|
||||||
Copy, adapt, and render. Each template uses project colors from visual-grammar-v01.md.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Architecture Diagram
|
|
||||||
|
|
||||||
System components, relationships, communication channels.
|
|
||||||
|
|
||||||
**When to use:** IPC bridge, perception pipeline, chunk loading, ECS system layout, client-server architecture.
|
|
||||||
|
|
||||||
**Agents:** Tyre (system architecture), Qatux (architecture decision records).
|
|
||||||
|
|
||||||
```d2
|
|
||||||
vars: {
|
|
||||||
color-bg: "#2a3040"
|
|
||||||
color-stroke: "#333340"
|
|
||||||
color-text: "#c8d0e0"
|
|
||||||
color-accent: "#c8d8f0"
|
|
||||||
}
|
|
||||||
|
|
||||||
direction: right
|
|
||||||
|
|
||||||
client: Godot Client {
|
|
||||||
shape: hexagon
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
rendering: Rendering {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
ui: UI Layer {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
bridge: IPC Bridge {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
style.stroke: ${color-accent}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server: Rust Server {
|
|
||||||
shape: hexagon
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
ecs: bevy_ecs {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
perception: Perception {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
bridge: IPC Bridge {
|
|
||||||
style.fill: ${color-bg}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
style.stroke: ${color-accent}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client.bridge -> server.bridge: "stdin/stdout" {
|
|
||||||
style.stroke: ${color-accent}
|
|
||||||
style.stroke-dash: 5
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Entity Relationship
|
|
||||||
|
|
||||||
Data schemas, ECS components, knowledge graph structure.
|
|
||||||
|
|
||||||
**When to use:** Database tables, component definitions, entity relationships, knowledge store schema.
|
|
||||||
|
|
||||||
**Agents:** Tyre (ECS component design), Qatux (schema documentation).
|
|
||||||
|
|
||||||
```d2
|
|
||||||
entity: Entity {
|
|
||||||
shape: sql_table
|
|
||||||
id: u64 {constraint: primary_key}
|
|
||||||
name: String
|
|
||||||
faction_id: u64 {constraint: foreign_key}
|
|
||||||
}
|
|
||||||
|
|
||||||
position: Position {
|
|
||||||
shape: sql_table
|
|
||||||
entity_id: u64 {constraint: foreign_key}
|
|
||||||
x: f32
|
|
||||||
y: f32
|
|
||||||
chunk_id: u32
|
|
||||||
}
|
|
||||||
|
|
||||||
knowledge: KnowledgeEntry {
|
|
||||||
shape: sql_table
|
|
||||||
observer_id: u64 {constraint: foreign_key}
|
|
||||||
subject_id: u64 {constraint: foreign_key}
|
|
||||||
fact_type: FactType
|
|
||||||
confidence: f32
|
|
||||||
last_seen_tick: u64
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.id -> position.entity_id
|
|
||||||
entity.id -> knowledge.observer_id
|
|
||||||
entity.id -> knowledge.subject_id
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Sequence / Data Flow
|
|
||||||
|
|
||||||
Ordered interactions between systems over time.
|
|
||||||
|
|
||||||
**When to use:** IPC message flow, tick processing, perception update cycle, dialogue system exchanges.
|
|
||||||
|
|
||||||
**Agents:** Tyre (system interaction design), Qatux (protocol documentation).
|
|
||||||
|
|
||||||
```d2
|
|
||||||
shape: sequence_diagram
|
|
||||||
|
|
||||||
client: Godot Client
|
|
||||||
bridge: IPC Bridge
|
|
||||||
server: Rust Server
|
|
||||||
ecs: ECS Systems
|
|
||||||
|
|
||||||
client -> bridge: TickRequest(delta, input)
|
|
||||||
bridge -> server: deserialize + dispatch
|
|
||||||
server -> ecs: run_systems(delta)
|
|
||||||
ecs -> ecs: perception, AI, physics
|
|
||||||
ecs -> server: collect WorldState
|
|
||||||
server -> bridge: serialize WorldState
|
|
||||||
bridge -> client: WorldState(entities, events)
|
|
||||||
client -> client: update rendering
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. State Machine
|
|
||||||
|
|
||||||
Entity states, transitions, conditions.
|
|
||||||
|
|
||||||
**When to use:** NPC behavior states, game mode transitions, dialogue state, investigation phases.
|
|
||||||
|
|
||||||
**Agents:** Tyre (behavior system design), Qatux (state documentation).
|
|
||||||
|
|
||||||
```d2
|
|
||||||
vars: {
|
|
||||||
color-state: "#2a3040"
|
|
||||||
color-text: "#c8d0e0"
|
|
||||||
color-edge: "#c8d8f0"
|
|
||||||
color-decision: "#333340"
|
|
||||||
}
|
|
||||||
|
|
||||||
idle: Idle {
|
|
||||||
style.fill: ${color-state}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
|
|
||||||
alert: Alert {
|
|
||||||
style.fill: ${color-state}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
|
|
||||||
investigate: Investigate {
|
|
||||||
style.fill: ${color-state}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
|
|
||||||
combat: Combat {
|
|
||||||
style.fill: ${color-state}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
style.stroke: "#f0b840"
|
|
||||||
}
|
|
||||||
|
|
||||||
flee: Flee {
|
|
||||||
style.fill: ${color-state}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
|
|
||||||
idle -> alert: "stimulus detected" { style.stroke: ${color-edge} }
|
|
||||||
alert -> investigate: "stimulus confirmed" { style.stroke: ${color-edge} }
|
|
||||||
alert -> idle: "timeout / stimulus lost" { style.stroke: ${color-edge}; style.stroke-dash: 5 }
|
|
||||||
investigate -> combat: "threat confirmed" { style.stroke: "#f0b840" }
|
|
||||||
investigate -> idle: "nothing found" { style.stroke: ${color-edge}; style.stroke-dash: 5 }
|
|
||||||
combat -> flee: "health < threshold" { style.stroke: "#f0b840" }
|
|
||||||
combat -> idle: "threat eliminated" { style.stroke: ${color-edge}; style.stroke-dash: 5 }
|
|
||||||
flee -> idle: "safe distance reached" { style.stroke: ${color-edge}; style.stroke-dash: 5 }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. UI Flow
|
|
||||||
|
|
||||||
Screen navigation, component hierarchy, interaction paths.
|
|
||||||
|
|
||||||
**When to use:** HUD layout relationships, menu navigation, dialogue flow, insert mode transitions.
|
|
||||||
|
|
||||||
**Agents:** Araminta (UI/visual design), Tyre (interface architecture), Qatux (UI documentation).
|
|
||||||
|
|
||||||
```d2
|
|
||||||
vars: {
|
|
||||||
color-screen: "#1a1e24"
|
|
||||||
color-panel: "#2a3040"
|
|
||||||
color-text: "#c8d0e0"
|
|
||||||
color-nav: "#c8d8f0"
|
|
||||||
}
|
|
||||||
|
|
||||||
gameplay: Gameplay {
|
|
||||||
style.fill: ${color-screen}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
hud: HUD {
|
|
||||||
style.fill: ${color-panel}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
minimap: Minimap
|
|
||||||
monologue: Monologue Panel
|
|
||||||
insert_display: Insert Display
|
|
||||||
}
|
|
||||||
|
|
||||||
world: World View {
|
|
||||||
style.fill: ${color-panel}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pause: Pause Menu {
|
|
||||||
style.fill: ${color-screen}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
inventory: Inventory
|
|
||||||
journal: Journal
|
|
||||||
settings: Settings
|
|
||||||
}
|
|
||||||
|
|
||||||
dialogue: Dialogue Mode {
|
|
||||||
style.fill: ${color-screen}
|
|
||||||
style.font-color: ${color-text}
|
|
||||||
|
|
||||||
speaker: Speaker Panel
|
|
||||||
responses: Response List
|
|
||||||
}
|
|
||||||
|
|
||||||
gameplay -> pause: "ESC" { style.stroke: ${color-nav} }
|
|
||||||
pause -> gameplay: "ESC / Resume" { style.stroke: ${color-nav}; style.stroke-dash: 5 }
|
|
||||||
gameplay -> dialogue: "interact with NPC" { style.stroke: ${color-nav} }
|
|
||||||
dialogue -> gameplay: "end conversation" { style.stroke: ${color-nav}; style.stroke-dash: 5 }
|
|
||||||
```
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
REPO_ROOT="$(cd "$SCRIPT_DIR" && git rev-parse --show-toplevel)"
|
|
||||||
RENDER="$SCRIPT_DIR/d2-render.sh"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: $(basename "$0") [directory] [options]
|
|
||||||
|
|
||||||
Batch render all .d2 files in a directory. Skips files whose PNG is
|
|
||||||
newer than the source unless --force is used.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--dry-run List files that would be rendered
|
|
||||||
--force Re-render even if SVG is up to date
|
|
||||||
--theme N Override theme for all files
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
$(basename "$0") # All in docs/diagrams/
|
|
||||||
$(basename "$0") docs/diagrams/architecture/ # One category
|
|
||||||
$(basename "$0") --dry-run # Preview
|
|
||||||
$(basename "$0") --force # Re-render everything
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
DIR="$REPO_ROOT/docs/diagrams"
|
|
||||||
DRY_RUN=false
|
|
||||||
FORCE=false
|
|
||||||
EXTRA_ARGS=()
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--dry-run) DRY_RUN=true; shift ;;
|
|
||||||
--force) FORCE=true; shift ;;
|
|
||||||
--theme) EXTRA_ARGS+=(--theme "$2"); shift 2 ;;
|
|
||||||
--help|-h) usage ;;
|
|
||||||
*)
|
|
||||||
if [[ -d "$1" ]] || [[ -d "$REPO_ROOT/$1" ]]; then
|
|
||||||
DIR="$1"
|
|
||||||
[[ "$DIR" != /* ]] && DIR="$REPO_ROOT/$DIR"
|
|
||||||
else
|
|
||||||
echo "Unknown option or directory: $1" >&2; exit 1
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
[[ ! -d "$DIR" ]] && { echo "ERROR: Directory not found: $DIR" >&2; exit 1; }
|
|
||||||
|
|
||||||
RENDERED=0
|
|
||||||
SKIPPED=0
|
|
||||||
FAILED=0
|
|
||||||
|
|
||||||
while IFS= read -r -d '' d2_file; do
|
|
||||||
png_file="${d2_file%.d2}.png"
|
|
||||||
|
|
||||||
# Skip if PNG is newer than source (unless --force)
|
|
||||||
if [[ "$FORCE" != true ]] && [[ -f "$png_file" ]] && [[ "$png_file" -nt "$d2_file" ]]; then
|
|
||||||
SKIPPED=$((SKIPPED + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
rel_path="${d2_file#"$REPO_ROOT/"}"
|
|
||||||
|
|
||||||
if [[ "$DRY_RUN" == true ]]; then
|
|
||||||
echo "Would render: $rel_path"
|
|
||||||
RENDERED=$((RENDERED + 1))
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if "$RENDER" "$d2_file" "${EXTRA_ARGS[@]+"${EXTRA_ARGS[@]}"}"; then
|
|
||||||
RENDERED=$((RENDERED + 1))
|
|
||||||
else
|
|
||||||
echo "FAILED: $rel_path" >&2
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
fi
|
|
||||||
done < <(find "$DIR" -name '*.d2' -print0 | sort -z)
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "Batch complete: $RENDERED rendered, $SKIPPED skipped (up to date), $FAILED failed"
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
D2="/home/linuxbrew/.linuxbrew/bin/d2"
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
||||||
REPO_ROOT="$(cd "$SCRIPT_DIR" && git rev-parse --show-toplevel)"
|
|
||||||
|
|
||||||
DEFAULT_THEME=200
|
|
||||||
DEFAULT_LAYOUT="dagre"
|
|
||||||
DEFAULT_PAD=100
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: $(basename "$0") [validate|fmt] <file.d2> [options]
|
|
||||||
|
|
||||||
Render a .d2 file to PNG with project defaults (theme $DEFAULT_THEME, $DEFAULT_LAYOUT layout).
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
validate <file> Check syntax without rendering
|
|
||||||
fmt <file> Auto-format in place
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--theme N Override theme (default: $DEFAULT_THEME)
|
|
||||||
--layout NAME Override layout engine (default: $DEFAULT_LAYOUT)
|
|
||||||
--sketch Enable hand-drawn sketch mode
|
|
||||||
--output PATH Override output path (default: input with .png extension)
|
|
||||||
--svg Render to SVG instead of PNG
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
$(basename "$0") docs/diagrams/architecture/ipc-bridge.d2
|
|
||||||
$(basename "$0") validate docs/diagrams/architecture/ipc-bridge.d2
|
|
||||||
$(basename "$0") docs/diagrams/architecture/ipc-bridge.d2 --sketch --theme 0
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
[[ $# -lt 1 ]] && usage
|
|
||||||
|
|
||||||
# Parse subcommand
|
|
||||||
SUBCMD=""
|
|
||||||
case "$1" in
|
|
||||||
validate|fmt)
|
|
||||||
SUBCMD="$1"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
[[ $# -lt 1 ]] && usage
|
|
||||||
|
|
||||||
INPUT="$1"
|
|
||||||
shift
|
|
||||||
|
|
||||||
# Resolve to absolute path
|
|
||||||
[[ "$INPUT" != /* ]] && INPUT="$REPO_ROOT/$INPUT"
|
|
||||||
|
|
||||||
[[ ! -f "$INPUT" ]] && { echo "ERROR: File not found: $INPUT" >&2; exit 1; }
|
|
||||||
|
|
||||||
# Handle subcommands
|
|
||||||
if [[ -n "$SUBCMD" ]]; then
|
|
||||||
"$D2" "$SUBCMD" "$INPUT"
|
|
||||||
echo "OK: $SUBCMD $INPUT"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse render options
|
|
||||||
THEME="$DEFAULT_THEME"
|
|
||||||
LAYOUT="$DEFAULT_LAYOUT"
|
|
||||||
SKETCH=""
|
|
||||||
OUTPUT=""
|
|
||||||
FORMAT="png"
|
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--theme) THEME="$2"; shift 2 ;;
|
|
||||||
--layout) LAYOUT="$2"; shift 2 ;;
|
|
||||||
--sketch) SKETCH="-s"; shift ;;
|
|
||||||
--output) OUTPUT="$2"; shift 2 ;;
|
|
||||||
--svg) FORMAT="svg"; shift ;;
|
|
||||||
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# Derive output path
|
|
||||||
if [[ -z "$OUTPUT" ]]; then
|
|
||||||
OUTPUT="${INPUT%.d2}.$FORMAT"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Render
|
|
||||||
"$D2" -t "$THEME" -l "$LAYOUT" --pad "$DEFAULT_PAD" $SKETCH "$INPUT" "$OUTPUT"
|
|
||||||
|
|
||||||
SIZE=$(stat --printf="%s" "$OUTPUT" 2>/dev/null || stat -f%z "$OUTPUT" 2>/dev/null)
|
|
||||||
echo "Rendered: $OUTPUT ($(( SIZE / 1024 ))KB)"
|
|
||||||
@@ -1,197 +0,0 @@
|
|||||||
---
|
|
||||||
name: frame0-wireframe
|
|
||||||
description: >
|
|
||||||
Create and export UI wireframes using Frame0 (local desktop wireframing
|
|
||||||
app with HTTP API). Use when the user says "create wireframe", "wireframe
|
|
||||||
this", "mock up the UI", "draw a screen", "UI layout", "wireframe the HUD",
|
|
||||||
"Frame0", "frame0", "export wireframe", or invokes /frame0-wireframe.
|
|
||||||
Wireframes are authored as local JSON files (source of truth) and synced
|
|
||||||
to Frame0 for rendering and export. Requires Frame0 to be running locally.
|
|
||||||
---
|
|
||||||
|
|
||||||
# Frame0 Wireframe Generation
|
|
||||||
|
|
||||||
Create UI wireframes as JSON files, sync them to Frame0 for rendering, and
|
|
||||||
export as PNG. Local JSON is the source of truth — Frame0 is the renderer.
|
|
||||||
|
|
||||||
**Frame0 is a renderer, not a workspace.** Treat it as disposable output.
|
|
||||||
Push freely, delete test pages, keep it clean. Never pull from Frame0 unless
|
|
||||||
the user explicitly says they have made edits in Frame0 and want to import
|
|
||||||
them. The pull workflow exists for that case only — do not use it proactively.
|
|
||||||
|
|
||||||
**Prerequisite:** Frame0 desktop app must be running. If not available,
|
|
||||||
stop and inform the user. Point to `references/setup-guide.md`.
|
|
||||||
|
|
||||||
## Health Check
|
|
||||||
|
|
||||||
Always check first:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.claude/skills/frame0-wireframe/scripts/frame0-cmd.sh health
|
|
||||||
```
|
|
||||||
|
|
||||||
## Core Workflow
|
|
||||||
|
|
||||||
1. **Health check** — verify Frame0 is running
|
|
||||||
2. **Write wireframe JSON** — to `docs/design/wireframes/{category}/{name}.json`
|
|
||||||
3. **Push to Frame0** — `frame0-sync.py push <file.json>`
|
|
||||||
4. **Export PNG** — `frame0-sync.py export <file.json> <output.png>`
|
|
||||||
5. **Clean up** — delete test/scratch pages from Frame0 when done
|
|
||||||
|
|
||||||
### Scripts
|
|
||||||
|
|
||||||
| Script | Purpose |
|
|
||||||
|--------|---------|
|
|
||||||
| `scripts/frame0-sync.py` | **Primary.** Push/pull/export wireframes between JSON and Frame0 |
|
|
||||||
| `scripts/frame0-cmd.sh` | Low-level API wrapper for ad-hoc commands |
|
|
||||||
|
|
||||||
## Wireframe JSON Format
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Dialogue Box",
|
|
||||||
"shapes": {
|
|
||||||
"panel": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 170, "top": 500, "width": 800, "height": 260,
|
|
||||||
"fillColor": "#1a1e24",
|
|
||||||
"strokeColor": "#333340",
|
|
||||||
"corners": [8, 8, 8, 8]
|
|
||||||
},
|
|
||||||
"speaker": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 520,
|
|
||||||
"text": "LERA KONSTANTIN",
|
|
||||||
"fontColor": "#c8d0e0",
|
|
||||||
"fontSize": 16
|
|
||||||
},
|
|
||||||
"btn-ask": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 670, "width": 370, "height": 30,
|
|
||||||
"fillColor": "#2a3040",
|
|
||||||
"strokeColor": "#c8d8f0",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"connectors": {
|
|
||||||
"flow-1": {
|
|
||||||
"tailId": "panel",
|
|
||||||
"headId": "btn-ask",
|
|
||||||
"strokeColor": "#c8d8f0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Key rules
|
|
||||||
|
|
||||||
- **Shape IDs are stable local IDs** you control (e.g. `"panel"`, `"btn-ask"`)
|
|
||||||
- **`parent`** references another local shape ID for nesting
|
|
||||||
- **`type`** uses create-API names: `Rectangle`, `Ellipse`, `Text`, `Line`
|
|
||||||
- **Colors** can be hex (`#2a3040`) or Frame0 theme tokens (`$slate6`)
|
|
||||||
- After a pull, Frame0 returns its native vocabulary (`Box` for Rectangle,
|
|
||||||
theme tokens for colors). The sync script handles the mapping transparently.
|
|
||||||
- The `.idmap.json` mapping file (gitignored) tracks local ID ↔ Frame0 ID
|
|
||||||
|
|
||||||
### Sync commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
SYNC=".claude/skills/frame0-wireframe/scripts/frame0-sync.py"
|
|
||||||
|
|
||||||
# Push local JSON to Frame0 (clears page, recreates all shapes)
|
|
||||||
$SYNC push docs/design/wireframes/dialogue/dialogue-box.json
|
|
||||||
|
|
||||||
# Pull Frame0 page back to local JSON (preserves local IDs via mapping)
|
|
||||||
$SYNC pull "Dialogue Box" docs/design/wireframes/dialogue/dialogue-box.json
|
|
||||||
|
|
||||||
# Push + export as PNG in one step
|
|
||||||
$SYNC export docs/design/wireframes/dialogue/dialogue-box.json \
|
|
||||||
docs/design/wireframes/dialogue/dialogue-box.png
|
|
||||||
```
|
|
||||||
|
|
||||||
### Batch export
|
|
||||||
|
|
||||||
Use this when exporting multiple wireframes. It runs as a single Bash call,
|
|
||||||
avoiding repeated permission prompts.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
BATCH=".claude/skills/frame0-wireframe/scripts/frame0-export-batch.sh"
|
|
||||||
|
|
||||||
# Dry run first — shows full manifest, no Frame0 calls
|
|
||||||
$BATCH --dry-run
|
|
||||||
|
|
||||||
# Export everything (skips PNGs already newer than their JSON)
|
|
||||||
$BATCH
|
|
||||||
|
|
||||||
# Export one category only
|
|
||||||
$BATCH --category dialogue
|
|
||||||
|
|
||||||
# Force re-export of everything
|
|
||||||
$BATCH --force
|
|
||||||
```
|
|
||||||
|
|
||||||
**Always dry-run first, then get approval before running the live export.**
|
|
||||||
|
|
||||||
## Low-Level Commands
|
|
||||||
|
|
||||||
For ad-hoc operations or exec calls not covered by sync:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
CMD=".claude/skills/frame0-wireframe/scripts/frame0-cmd.sh"
|
|
||||||
$CMD health
|
|
||||||
$CMD list-pages
|
|
||||||
$CMD current-page
|
|
||||||
$CMD get-page <page-id>
|
|
||||||
$CMD create-shape Rectangle '{"name":"btn","left":100,"top":100,"width":120,"height":36}'
|
|
||||||
$CMD create-connector <tail-id> <head-id>
|
|
||||||
$CMD move <shape-id> <dx> <dy>
|
|
||||||
$CMD export --format image/png
|
|
||||||
$CMD exec "view:fit-to-screen" '{}'
|
|
||||||
```
|
|
||||||
|
|
||||||
If you find yourself using `exec` for the same command repeatedly, flag it as
|
|
||||||
a candidate for a proper wrapper in `frame0-cmd.sh`.
|
|
||||||
|
|
||||||
## Project Styling Defaults
|
|
||||||
|
|
||||||
Colors from `docs/design/visual-grammar-v01.md`:
|
|
||||||
|
|
||||||
| Role | Hex | Frame0 token |
|
|
||||||
|------|-----|-------------|
|
|
||||||
| Background | `#1a1e24` | `$sage3` |
|
|
||||||
| Stroke | `#333340` | `$slate6` |
|
|
||||||
| Fill | `#2a3040` | `$slate5` |
|
|
||||||
| Text | `#c8d0e0` | `$mint12` |
|
|
||||||
| Accent | `#c8d8f0` | `$blue12` |
|
|
||||||
|
|
||||||
Use hex when authoring new wireframes. Frame0 maps them to theme tokens on push.
|
|
||||||
|
|
||||||
## Output Convention
|
|
||||||
|
|
||||||
```
|
|
||||||
docs/design/wireframes/
|
|
||||||
hud/ # HUD layout wireframes
|
|
||||||
menus/ # Menu screen wireframes
|
|
||||||
dialogue/ # Dialogue box wireframes
|
|
||||||
insert/ # Neural insert wireframes
|
|
||||||
```
|
|
||||||
|
|
||||||
Both `.json` source and `.png` exports are tracked in git.
|
|
||||||
`.idmap.json` mapping files are gitignored.
|
|
||||||
|
|
||||||
## Agent Guidance
|
|
||||||
|
|
||||||
- **Araminta** — Primary user. Full wireframe creation, layout iteration,
|
|
||||||
visual consistency. Uses all component library patterns.
|
|
||||||
- **Tyre** — Interface architecture wireframes. System boundary diagrams.
|
|
||||||
- **Qatux** — Export wireframes for UI decision records and documentation.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- `references/component-library.md` — Pre-built JSON wireframe templates
|
|
||||||
(HUD, dialogue, menus, modals, lists, inventory). Copy and adapt.
|
|
||||||
- `references/api-reference.md` — Frame0 HTTP API command reference and
|
|
||||||
type mappings. Read for low-level control.
|
|
||||||
- `references/setup-guide.md` — Frame0 installation and startup for Fedora.
|
|
||||||
@@ -1,241 +0,0 @@
|
|||||||
# Frame0 HTTP API Reference
|
|
||||||
|
|
||||||
Frame0 exposes a local HTTP API when the desktop app is running.
|
|
||||||
|
|
||||||
## Endpoint
|
|
||||||
|
|
||||||
```
|
|
||||||
POST http://localhost:{port}/execute_command
|
|
||||||
Content-Type: application/json
|
|
||||||
```
|
|
||||||
|
|
||||||
Default port: **58320** (override via `FRAME0_PORT` env var or `--port` flag).
|
|
||||||
|
|
||||||
## Request / Response
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "namespace:action", "args": { ... }}
|
|
||||||
```
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"success": true, "data": { ... }}
|
|
||||||
{"success": false, "error": "description"}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Type Mapping
|
|
||||||
|
|
||||||
Frame0 uses different type names for create vs get:
|
|
||||||
|
|
||||||
| Create API (`type`) | Get API (internal) | Description |
|
|
||||||
|--------------------|--------------------|-------------|
|
|
||||||
| `Rectangle` | `Box` | Rectangle with optional corners |
|
|
||||||
| `Ellipse` | `Ellipse` | Circle/ellipse |
|
|
||||||
| `Text` | `Text` | Text label |
|
|
||||||
| `Line` | `Line` | Line/polyline |
|
|
||||||
| `Frame` | `Frame` | Container from library |
|
|
||||||
| `Freehand` | `Freehand` | Freehand drawing |
|
|
||||||
| `Highlighter` | `Highlighter` | Highlighter stroke |
|
|
||||||
|
|
||||||
The sync script handles this mapping transparently.
|
|
||||||
|
|
||||||
## Color Tokens
|
|
||||||
|
|
||||||
Frame0 maps hex colors to theme tokens on creation (`convertColors: true`):
|
|
||||||
|
|
||||||
| Hex | Token | Role |
|
|
||||||
|-----|-------|------|
|
|
||||||
| `#1a1e24` | `$sage3` | Background |
|
|
||||||
| `#2a3040` | `$slate5` | Fill |
|
|
||||||
| `#333340` | `$slate6` | Stroke |
|
|
||||||
| `#c8d0e0` | `$mint12` | Text |
|
|
||||||
| `#c8d8f0` | `$blue12` | Accent |
|
|
||||||
|
|
||||||
Both hex and token strings work in the API. Tokens are preserved on round-trip.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
### shape:create-shape
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "shape:create-shape",
|
|
||||||
"args": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"shapeProps": {
|
|
||||||
"name": "my-button",
|
|
||||||
"left": 100, "top": 200, "width": 120, "height": 36,
|
|
||||||
"fillColor": "#2a3040",
|
|
||||||
"strokeColor": "#c8d8f0",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"parentId": "optional-parent-shape-id",
|
|
||||||
"convertColors": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns: shape ID (string).
|
|
||||||
|
|
||||||
### shape:get-shape
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "shape:get-shape", "args": {"shapeId": "id"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:update-shape
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "shape:update-shape",
|
|
||||||
"args": {
|
|
||||||
"shapeId": "id",
|
|
||||||
"shapeProps": {"fillColor": "#1a1e24", "text": "Updated"},
|
|
||||||
"convertColors": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:move
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "shape:move", "args": {"shapeId": "id", "dx": 50, "dy": -20}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:create-connector
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "shape:create-connector",
|
|
||||||
"args": {
|
|
||||||
"tailId": "source-id",
|
|
||||||
"headId": "target-id",
|
|
||||||
"shapeProps": {"strokeColor": "#c8d8f0"},
|
|
||||||
"convertColors": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:create-icon
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "shape:create-icon",
|
|
||||||
"args": {
|
|
||||||
"iconName": "search",
|
|
||||||
"shapeProps": {"left": 100, "top": 100, "width": 24, "height": 24}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:get-available-icons
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "shape:get-available-icons", "args": {}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### shape:group / shape:ungroup
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "shape:group", "args": {"shapeIdArray": ["id1", "id2"]}}
|
|
||||||
{"command": "shape:ungroup", "args": {"shapeIdArray": ["group-id"]}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### edit:delete / edit:duplicate
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "edit:delete", "args": {"shapeIdArray": ["id1", "id2"]}}
|
|
||||||
{"command": "edit:duplicate", "args": {"shapeIdArray": ["id"], "dx": 20, "dy": 0}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### page:add
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "page:add", "args": {"pageProps": {"name": "Page Name"}}}
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns: `{id, type, name}`.
|
|
||||||
|
|
||||||
### page:get
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "page:get", "args": {"pageId": "id", "exportShapes": true}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### page:get-current-page
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "page:get-current-page", "args": {}}
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns: page ID string.
|
|
||||||
|
|
||||||
### page:set-current-page
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "page:set-current-page", "args": {"pageId": "id"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### doc:get (list all pages)
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "doc:get", "args": {"exportPages": true, "exportShapes": false}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### page:delete
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "page:delete", "args": {"pageId": "id"}}
|
|
||||||
```
|
|
||||||
|
|
||||||
### file:export-image
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"command": "file:export-image",
|
|
||||||
"args": {
|
|
||||||
"pageId": "optional-page-id",
|
|
||||||
"format": "image/png",
|
|
||||||
"fillBackground": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Formats: `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`.
|
|
||||||
Returns: base64-encoded image data.
|
|
||||||
|
|
||||||
### view:fit-to-screen
|
|
||||||
|
|
||||||
```json
|
|
||||||
{"command": "view:fit-to-screen", "args": {}}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Shape Properties
|
|
||||||
|
|
||||||
| Property | Type | Notes |
|
|
||||||
|----------|------|-------|
|
|
||||||
| `name` | string | Shape identifier/label |
|
|
||||||
| `left` | number | X position (origin: top-left) |
|
|
||||||
| `top` | number | Y position |
|
|
||||||
| `width` | number | Width in pixels |
|
|
||||||
| `height` | number | Height in pixels |
|
|
||||||
| `fillColor` | string | Hex or `$token` |
|
|
||||||
| `strokeColor` | string | Hex or `$token` |
|
|
||||||
| `strokeWidth` | number | Border width |
|
|
||||||
| `fontColor` | string | Text color (hex or `$token`) |
|
|
||||||
| `fontSize` | number | Font size in pixels |
|
|
||||||
| `fontFamily` | string | Font name (Frame0 default: `Loranthus`) |
|
|
||||||
| `text` | string | Text content |
|
|
||||||
| `wordWrap` | boolean | Enable word wrapping |
|
|
||||||
| `corners` | number[4] | Border radius [TL, TR, BR, BL] |
|
|
||||||
| `roughness` | number | Sketch roughness (Frame0 default: 1) |
|
|
||||||
| `constraints` | array | Auto-sizing constraints |
|
|
||||||
| `horzAlign` | string | Horizontal text alignment |
|
|
||||||
| `vertAlign` | string | Vertical text alignment |
|
|
||||||
| `fillStyle` | string | Fill style (`none` for transparent) |
|
|
||||||
| `path` | array | Coordinate pairs for lines |
|
|
||||||
@@ -1,467 +0,0 @@
|
|||||||
# Component Library
|
|
||||||
|
|
||||||
Pre-built wireframe JSON templates for The Settled Reach UI. Copy the JSON,
|
|
||||||
adapt positions/sizes, save to `docs/design/wireframes/{category}/`, and push.
|
|
||||||
|
|
||||||
**Viewport:** 1140x780 (Godot project settings)
|
|
||||||
**Grid unit:** 8px
|
|
||||||
**Min touch target:** 36px height
|
|
||||||
**Font sizes:** 12 (label), 14 (body), 16 (subtitle), 18 (heading), 24 (title)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. HUD Layout
|
|
||||||
|
|
||||||
Main gameplay overlay. Minimap top-right, monologue bottom-center,
|
|
||||||
insert display bottom-left, action hints bottom-right.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "HUD Layout",
|
|
||||||
"shapes": {
|
|
||||||
"minimap": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 880, "top": 20, "width": 240, "height": 240,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"minimap-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "minimap",
|
|
||||||
"left": 890, "top": 30,
|
|
||||||
"text": "Minimap",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"monologue": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 300, "top": 680, "width": 520, "height": 80,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"monologue-text": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "monologue",
|
|
||||||
"left": 310, "top": 700, "width": 500,
|
|
||||||
"text": "Internal monologue text appears here...",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 13, "wordWrap": true
|
|
||||||
},
|
|
||||||
"insert": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 20, "top": 600, "width": 260, "height": 160,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"insert-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "insert",
|
|
||||||
"left": 30, "top": 620,
|
|
||||||
"text": "Neural Insert Data",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"hints": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 880, "top": 700, "width": 240, "height": 60,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"hints-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "hints",
|
|
||||||
"left": 890, "top": 720,
|
|
||||||
"text": "[E] Interact [TAB] Insert",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Dialogue Box
|
|
||||||
|
|
||||||
Speaker panel with response options. Anchored bottom-center during dialogue mode.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Dialogue Box",
|
|
||||||
"shapes": {
|
|
||||||
"panel": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 170, "top": 500, "width": 800, "height": 260,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [8, 8, 8, 8]
|
|
||||||
},
|
|
||||||
"speaker": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 520,
|
|
||||||
"text": "LERA KONSTANTIN",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 16
|
|
||||||
},
|
|
||||||
"text-area": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 550, "width": 760, "height": 100,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"dialogue-text": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "text-area",
|
|
||||||
"left": 200, "top": 560, "width": 740,
|
|
||||||
"text": "You look like you could use a drink. First time on the station?",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14, "wordWrap": true
|
|
||||||
},
|
|
||||||
"btn-option1": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 670, "width": 370, "height": 30,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-option1-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "btn-option1",
|
|
||||||
"left": 200, "top": 674,
|
|
||||||
"text": "[1] Ask about the station",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 12
|
|
||||||
},
|
|
||||||
"btn-option2": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 190, "top": 710, "width": 370, "height": 30,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-option2-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "btn-option2",
|
|
||||||
"left": 200, "top": 714,
|
|
||||||
"text": "[2] Ask about recent events",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 12
|
|
||||||
},
|
|
||||||
"btn-leave": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "panel",
|
|
||||||
"left": 580, "top": 670, "width": 180, "height": 30,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-leave-label": {
|
|
||||||
"type": "Text",
|
|
||||||
"parent": "btn-leave",
|
|
||||||
"left": 590, "top": 674,
|
|
||||||
"text": "[3] Leave",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Menu Screen
|
|
||||||
|
|
||||||
Full-screen menu with sidebar navigation and content area.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Pause Menu",
|
|
||||||
"shapes": {
|
|
||||||
"bg": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 0, "top": 0, "width": 1140, "height": 780,
|
|
||||||
"fillColor": "#1a1e24"
|
|
||||||
},
|
|
||||||
"nav": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "bg",
|
|
||||||
"left": 20, "top": 20, "width": 200, "height": 740,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-inventory": {
|
|
||||||
"type": "Rectangle", "parent": "nav",
|
|
||||||
"left": 30, "top": 40, "width": 180, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-inventory-label": {
|
|
||||||
"type": "Text", "parent": "btn-inventory",
|
|
||||||
"left": 40, "top": 48, "text": "Inventory",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-journal": {
|
|
||||||
"type": "Rectangle", "parent": "nav",
|
|
||||||
"left": 30, "top": 86, "width": 180, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-journal-label": {
|
|
||||||
"type": "Text", "parent": "btn-journal",
|
|
||||||
"left": 40, "top": 94, "text": "Journal",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-map": {
|
|
||||||
"type": "Rectangle", "parent": "nav",
|
|
||||||
"left": 30, "top": 132, "width": 180, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-map-label": {
|
|
||||||
"type": "Text", "parent": "btn-map",
|
|
||||||
"left": 40, "top": 140, "text": "Map",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-settings": {
|
|
||||||
"type": "Rectangle", "parent": "nav",
|
|
||||||
"left": 30, "top": 178, "width": 180, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-settings-label": {
|
|
||||||
"type": "Text", "parent": "btn-settings",
|
|
||||||
"left": 40, "top": 186, "text": "Settings",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-resume": {
|
|
||||||
"type": "Rectangle", "parent": "nav",
|
|
||||||
"left": 30, "top": 720, "width": 180, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-resume-label": {
|
|
||||||
"type": "Text", "parent": "btn-resume",
|
|
||||||
"left": 40, "top": 728, "text": "Resume",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"content": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "bg",
|
|
||||||
"left": 240, "top": 20, "width": 880, "height": 740,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340",
|
|
||||||
"corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"content-label": {
|
|
||||||
"type": "Text", "parent": "content",
|
|
||||||
"left": 260, "top": 40,
|
|
||||||
"text": "Content area",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Modal Dialog
|
|
||||||
|
|
||||||
Centered overlay for confirmations, alerts, choices.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Modal Dialog",
|
|
||||||
"shapes": {
|
|
||||||
"overlay": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 0, "top": 0, "width": 1140, "height": 780,
|
|
||||||
"fillColor": "#0a0c10"
|
|
||||||
},
|
|
||||||
"modal": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"parent": "overlay",
|
|
||||||
"left": 320, "top": 240, "width": 500, "height": 300,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340",
|
|
||||||
"corners": [8, 8, 8, 8]
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"type": "Text", "parent": "modal",
|
|
||||||
"left": 340, "top": 260,
|
|
||||||
"text": "Confirm Action",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 18
|
|
||||||
},
|
|
||||||
"divider": {
|
|
||||||
"type": "Line", "parent": "modal",
|
|
||||||
"left": 340, "top": 290, "width": 460, "height": 0,
|
|
||||||
"strokeColor": "#333340"
|
|
||||||
},
|
|
||||||
"body-1": {
|
|
||||||
"type": "Text", "parent": "modal",
|
|
||||||
"left": 340, "top": 310,
|
|
||||||
"text": "Are you sure you want to proceed?",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"body-2": {
|
|
||||||
"type": "Text", "parent": "modal",
|
|
||||||
"left": 340, "top": 340,
|
|
||||||
"text": "This action cannot be undone.",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-cancel": {
|
|
||||||
"type": "Rectangle", "parent": "modal",
|
|
||||||
"left": 480, "top": 480, "width": 120, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-cancel-label": {
|
|
||||||
"type": "Text", "parent": "btn-cancel",
|
|
||||||
"left": 510, "top": 488,
|
|
||||||
"text": "Cancel",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"btn-confirm": {
|
|
||||||
"type": "Rectangle", "parent": "modal",
|
|
||||||
"left": 620, "top": 480, "width": 120, "height": 36,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"btn-confirm-label": {
|
|
||||||
"type": "Text", "parent": "btn-confirm",
|
|
||||||
"left": 645, "top": 488,
|
|
||||||
"text": "Confirm",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. List View
|
|
||||||
|
|
||||||
Scrollable list with item selection and detail panel.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "List View",
|
|
||||||
"shapes": {
|
|
||||||
"list-panel": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 20, "top": 20, "width": 400, "height": 740,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"item-1": {
|
|
||||||
"type": "Rectangle", "parent": "list-panel",
|
|
||||||
"left": 30, "top": 30, "width": 380, "height": 40,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#c8d8f0", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"item-1-label": {
|
|
||||||
"type": "Text", "parent": "item-1",
|
|
||||||
"left": 40, "top": 38, "text": "Item Alpha",
|
|
||||||
"fontColor": "#c8d8f0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"item-2": {
|
|
||||||
"type": "Rectangle", "parent": "list-panel",
|
|
||||||
"left": 30, "top": 80, "width": 380, "height": 40,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"item-2-label": {
|
|
||||||
"type": "Text", "parent": "item-2",
|
|
||||||
"left": 40, "top": 88, "text": "Item Beta",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"item-3": {
|
|
||||||
"type": "Rectangle", "parent": "list-panel",
|
|
||||||
"left": 30, "top": 130, "width": 380, "height": 40,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"item-3-label": {
|
|
||||||
"type": "Text", "parent": "item-3",
|
|
||||||
"left": 40, "top": 138, "text": "Item Gamma",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14
|
|
||||||
},
|
|
||||||
"detail-panel": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 440, "top": 20, "width": 680, "height": 740,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"detail-title": {
|
|
||||||
"type": "Text", "parent": "detail-panel",
|
|
||||||
"left": 460, "top": 40,
|
|
||||||
"text": "Item Alpha",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 18
|
|
||||||
},
|
|
||||||
"detail-body": {
|
|
||||||
"type": "Text", "parent": "detail-panel",
|
|
||||||
"left": 460, "top": 80, "width": 640,
|
|
||||||
"text": "Description and properties appear here.",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14, "wordWrap": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Inventory Grid
|
|
||||||
|
|
||||||
Grid of cells for item management.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"name": "Inventory Grid",
|
|
||||||
"shapes": {
|
|
||||||
"panel": {
|
|
||||||
"type": "Rectangle",
|
|
||||||
"left": 240, "top": 100, "width": 660, "height": 580,
|
|
||||||
"fillColor": "#1a1e24", "strokeColor": "#333340", "corners": [8, 8, 8, 8]
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"type": "Text", "parent": "panel",
|
|
||||||
"left": 260, "top": 120,
|
|
||||||
"text": "INVENTORY",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 18
|
|
||||||
},
|
|
||||||
"cell-1-1": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 260, "top": 160, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-1-2": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 332, "top": 160, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-1-3": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 404, "top": 160, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-1-4": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 476, "top": 160, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-2-1": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 260, "top": 232, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-2-2": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 332, "top": 232, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-2-3": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 404, "top": 232, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"cell-2-4": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 476, "top": 232, "width": 64, "height": 64,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"detail": {
|
|
||||||
"type": "Rectangle", "parent": "panel",
|
|
||||||
"left": 580, "top": 160, "width": 300, "height": 400,
|
|
||||||
"fillColor": "#2a3040", "strokeColor": "#333340", "corners": [4, 4, 4, 4]
|
|
||||||
},
|
|
||||||
"detail-title": {
|
|
||||||
"type": "Text", "parent": "detail",
|
|
||||||
"left": 600, "top": 180,
|
|
||||||
"text": "Selected Item Name",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 16
|
|
||||||
},
|
|
||||||
"detail-body": {
|
|
||||||
"type": "Text", "parent": "detail",
|
|
||||||
"left": 600, "top": 210, "width": 260,
|
|
||||||
"text": "Item description and stats",
|
|
||||||
"fontColor": "#c8d0e0", "fontSize": 14, "wordWrap": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
# Frame0 Setup Guide
|
|
||||||
|
|
||||||
## Installation (Fedora)
|
|
||||||
|
|
||||||
Download from https://frame0.app/download and install the RPM:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo dnf install ./frame0-*.x86_64.rpm
|
|
||||||
```
|
|
||||||
|
|
||||||
Requires: Fedora 40 or later (x86_64).
|
|
||||||
|
|
||||||
## Starting Frame0
|
|
||||||
|
|
||||||
Launch the desktop application:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
frame0 &
|
|
||||||
```
|
|
||||||
|
|
||||||
Frame0 exposes an HTTP API at `localhost:58320` when running.
|
|
||||||
|
|
||||||
## Verify API Access
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.claude/skills/frame0-wireframe/scripts/frame0-cmd.sh health
|
|
||||||
```
|
|
||||||
|
|
||||||
Expected output: `Frame0 is running on port 58320`
|
|
||||||
|
|
||||||
## Port Configuration
|
|
||||||
|
|
||||||
Default port: **58320**
|
|
||||||
|
|
||||||
To use a different port, set the environment variable:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export FRAME0_PORT=58321
|
|
||||||
```
|
|
||||||
|
|
||||||
Or pass `--port` to any script:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
.claude/skills/frame0-wireframe/scripts/frame0-cmd.sh --port 58321 health
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
| Symptom | Cause | Fix |
|
|
||||||
|---------|-------|-----|
|
|
||||||
| "Connection refused" | Frame0 not running | Start the desktop app |
|
|
||||||
| "Port in use" | Another instance running | Close duplicate or use different port |
|
|
||||||
| Script hangs | API unresponsive | Restart Frame0 |
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
PORT="${FRAME0_PORT:-58320}"
|
|
||||||
ENDPOINT="http://localhost:${PORT}/execute_command"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<EOF
|
|
||||||
Usage: $(basename "$0") <command> [args...] [--port N]
|
|
||||||
|
|
||||||
Low-level Frame0 HTTP API wrapper. Replaces the MCP server with direct
|
|
||||||
curl calls. Requires Frame0 desktop app to be running.
|
|
||||||
|
|
||||||
Commands:
|
|
||||||
health Check if Frame0 is running
|
|
||||||
exec <namespace:action> <json> Execute a raw API command
|
|
||||||
create-shape <type> <json-props> Create a shape (Rectangle, Ellipse, Text, Line)
|
|
||||||
get-shape <id> Get shape details
|
|
||||||
update-shape <id> <json-props> Update shape properties
|
|
||||||
delete <id> [id...] Delete shapes by ID
|
|
||||||
move <id> <dx> <dy> Move a shape by pixel offset
|
|
||||||
duplicate <id> Duplicate a shape
|
|
||||||
group <id> [id...] Group shapes
|
|
||||||
ungroup <group-id> Ungroup a group
|
|
||||||
create-connector <tail-id> <head-id> [json-props] Connect two shapes
|
|
||||||
create-icon <name> <json-props> Create an icon shape
|
|
||||||
add-page <name> Add a new page (becomes current)
|
|
||||||
get-page [page-id] Get current or specific page data
|
|
||||||
list-pages [--shapes] List all pages (--shapes for shape data)
|
|
||||||
current-page Get current page ID
|
|
||||||
set-page <page-id> Set current page
|
|
||||||
export [page-id] [--format mime] Export page as image (default: image/png)
|
|
||||||
fit Fit view to screen
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--port N Frame0 API port (default: $PORT, env: FRAME0_PORT)
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
$(basename "$0") health
|
|
||||||
$(basename "$0") add-page "HUD Layout"
|
|
||||||
$(basename "$0") create-shape Rectangle '{"name":"btn","left":100,"top":100,"width":120,"height":36}'
|
|
||||||
$(basename "$0") list-pages
|
|
||||||
$(basename "$0") export --format image/png
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse --port from anywhere in args
|
|
||||||
ARGS=()
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--port) PORT="$2"; ENDPOINT="http://localhost:${PORT}/execute_command"; shift 2 ;;
|
|
||||||
*) ARGS+=("$1"); shift ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
set -- "${ARGS[@]+"${ARGS[@]}"}"
|
|
||||||
|
|
||||||
[[ $# -lt 1 ]] && usage
|
|
||||||
|
|
||||||
# Execute a Frame0 API command, return data or error
|
|
||||||
frame0_exec() {
|
|
||||||
local command="$1"
|
|
||||||
local args
|
|
||||||
args="${2:-"{}"}"
|
|
||||||
|
|
||||||
local response
|
|
||||||
response=$(curl -s -w "\n%{http_code}" -X POST "$ENDPOINT" \
|
|
||||||
-H "Content-Type: application/json" \
|
|
||||||
-d "{\"command\": \"$command\", \"args\": $args}" 2>&1) || {
|
|
||||||
echo "ERROR: Cannot connect to Frame0 at localhost:$PORT" >&2
|
|
||||||
echo "Is Frame0 running? See: .claude/skills/frame0-wireframe/references/setup-guide.md" >&2
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
local http_code body
|
|
||||||
http_code=$(echo "$response" | tail -1)
|
|
||||||
body=$(echo "$response" | sed '$d')
|
|
||||||
|
|
||||||
if [[ "$http_code" != 2* ]]; then
|
|
||||||
echo "ERROR: HTTP $http_code from Frame0" >&2
|
|
||||||
echo "$body" >&2
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Parse success/error from response
|
|
||||||
python3 -c "
|
|
||||||
import sys, json
|
|
||||||
try:
|
|
||||||
r = json.loads(sys.stdin.read())
|
|
||||||
if r.get('success'):
|
|
||||||
d = r.get('data')
|
|
||||||
if d is not None:
|
|
||||||
print(json.dumps(d, indent=2))
|
|
||||||
else:
|
|
||||||
print('ERROR: ' + str(r.get('error', 'Unknown error')), file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
except json.JSONDecodeError as e:
|
|
||||||
print(f'ERROR: Invalid JSON response: {e}', file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
" <<< "$body"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build JSON array from remaining args
|
|
||||||
ids_to_json_array() {
|
|
||||||
local arr="["
|
|
||||||
local first=true
|
|
||||||
for id in "$@"; do
|
|
||||||
[[ "$first" == true ]] && first=false || arr+=","
|
|
||||||
arr+="\"$id\""
|
|
||||||
done
|
|
||||||
arr+="]"
|
|
||||||
echo "$arr"
|
|
||||||
}
|
|
||||||
|
|
||||||
CMD="${1:-}"
|
|
||||||
shift || true
|
|
||||||
|
|
||||||
case "$CMD" in
|
|
||||||
health)
|
|
||||||
if curl -s -o /dev/null -w "%{http_code}" "http://localhost:${PORT}/" 2>/dev/null | grep -q "^[23]"; then
|
|
||||||
echo "Frame0 is running on port $PORT"
|
|
||||||
else
|
|
||||||
echo "Frame0 is NOT running on port $PORT" >&2
|
|
||||||
echo "Start Frame0 desktop app, then retry." >&2
|
|
||||||
echo "See: .claude/skills/frame0-wireframe/references/setup-guide.md" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
exec)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: exec <command> <json-args>" >&2; exit 1; }
|
|
||||||
frame0_exec "$1" "$2"
|
|
||||||
;;
|
|
||||||
|
|
||||||
create-shape)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: create-shape <Type> <json-props>" >&2; exit 1; }
|
|
||||||
local_type="$1"
|
|
||||||
local_props="$2"
|
|
||||||
local_parent="${3:-}"
|
|
||||||
local_parent_arg=""
|
|
||||||
[[ -n "$local_parent" ]] && local_parent_arg=", \"parentId\": \"$local_parent\""
|
|
||||||
frame0_exec "shape:create-shape" "{\"type\": \"$local_type\", \"shapeProps\": $local_props$local_parent_arg, \"convertColors\": true}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
get-shape)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: get-shape <id>" >&2; exit 1; }
|
|
||||||
frame0_exec "shape:get-shape" "{\"shapeId\": \"$1\"}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
update-shape)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: update-shape <id> <json-props>" >&2; exit 1; }
|
|
||||||
frame0_exec "shape:update-shape" "{\"shapeId\": \"$1\", \"shapeProps\": $2, \"convertColors\": true}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
delete)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: delete <id> [id...]" >&2; exit 1; }
|
|
||||||
local_arr=$(ids_to_json_array "$@")
|
|
||||||
frame0_exec "edit:delete" "{\"shapeIdArray\": $local_arr}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
move)
|
|
||||||
[[ $# -lt 3 ]] && { echo "Usage: move <id> <dx> <dy>" >&2; exit 1; }
|
|
||||||
frame0_exec "shape:move" "{\"shapeId\": \"$1\", \"dx\": $2, \"dy\": $3}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
duplicate)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: duplicate <id> [dx] [dy]" >&2; exit 1; }
|
|
||||||
local_dx="${2:-0}"
|
|
||||||
local_dy="${3:-0}"
|
|
||||||
frame0_exec "edit:duplicate" "{\"shapeIdArray\": [\"$1\"], \"dx\": $local_dx, \"dy\": $local_dy}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
group)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: group <id> <id> [id...]" >&2; exit 1; }
|
|
||||||
local_arr=$(ids_to_json_array "$@")
|
|
||||||
frame0_exec "shape:group" "{\"shapeIdArray\": $local_arr}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
ungroup)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: ungroup <group-id>" >&2; exit 1; }
|
|
||||||
frame0_exec "shape:ungroup" "{\"shapeIdArray\": [\"$1\"]}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
create-connector)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: create-connector <tail-id> <head-id> [json-props]" >&2; exit 1; }
|
|
||||||
local_props="${3:-{}}"
|
|
||||||
frame0_exec "shape:create-connector" "{\"tailId\": \"$1\", \"headId\": \"$2\", \"shapeProps\": $local_props, \"convertColors\": true}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
create-icon)
|
|
||||||
[[ $# -lt 2 ]] && { echo "Usage: create-icon <name> <json-props>" >&2; exit 1; }
|
|
||||||
frame0_exec "shape:create-icon" "{\"iconName\": \"$1\", \"shapeProps\": $2, \"convertColors\": true}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
add-page)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: add-page <name>" >&2; exit 1; }
|
|
||||||
frame0_exec "page:add" "{\"pageProps\": {\"name\": \"$1\"}}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
get-page)
|
|
||||||
if [[ $# -ge 1 ]]; then
|
|
||||||
frame0_exec "page:get" "{\"pageId\": \"$1\", \"exportShapes\": true}"
|
|
||||||
else
|
|
||||||
local_id
|
|
||||||
local_id=$(frame0_exec "page:get-current-page")
|
|
||||||
# Strip quotes from returned ID
|
|
||||||
local_id=$(echo "$local_id" | tr -d '"')
|
|
||||||
frame0_exec "page:get" "{\"pageId\": \"$local_id\", \"exportShapes\": true}"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
list-pages)
|
|
||||||
local_shapes="false"
|
|
||||||
[[ "${1:-}" == "--shapes" ]] && local_shapes="true"
|
|
||||||
frame0_exec "doc:get" "{\"exportPages\": true, \"exportShapes\": $local_shapes}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
current-page)
|
|
||||||
frame0_exec "page:get-current-page"
|
|
||||||
;;
|
|
||||||
|
|
||||||
set-page)
|
|
||||||
[[ $# -lt 1 ]] && { echo "Usage: set-page <page-id>" >&2; exit 1; }
|
|
||||||
frame0_exec "page:set-current-page" "{\"pageId\": \"$1\"}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
export)
|
|
||||||
local_page_id=""
|
|
||||||
local_format="image/png"
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--format) local_format="$2"; shift 2 ;;
|
|
||||||
*) local_page_id="$1"; shift ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
local_page_arg=""
|
|
||||||
[[ -n "$local_page_id" ]] && local_page_arg="\"pageId\": \"$local_page_id\", "
|
|
||||||
frame0_exec "file:export-image" "{${local_page_arg}\"format\": \"$local_format\", \"fillBackground\": true}"
|
|
||||||
;;
|
|
||||||
|
|
||||||
fit)
|
|
||||||
frame0_exec "view:fit-to-screen"
|
|
||||||
;;
|
|
||||||
|
|
||||||
--help|-h|help)
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
echo "Unknown command: $CMD" >&2
|
|
||||||
usage
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Batch export wireframes from JSON to PNG via Frame0.
|
|
||||||
#
|
|
||||||
# Finds all .json wireframe files under docs/design/wireframes/ and exports
|
|
||||||
# each to a matching .png. Skips files whose PNG is already newer than the
|
|
||||||
# JSON, unless --force is passed.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# frame0-export-batch.sh [--dry-run] [--force] [--category CAT] [--root DIR]
|
|
||||||
#
|
|
||||||
# Options:
|
|
||||||
# --dry-run Print manifest only, don't touch Frame0.
|
|
||||||
# --force Re-export even if PNG already exists and is up to date.
|
|
||||||
# --category CAT Limit to one subdirectory (e.g. --category dialogue)
|
|
||||||
# --root DIR Wireframes root dir (default: docs/design/wireframes)
|
|
||||||
#
|
|
||||||
# Exit codes:
|
|
||||||
# 0 All exports succeeded (or nothing to do)
|
|
||||||
# 1 One or more exports failed
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
|
|
||||||
SYNC="$SCRIPT_DIR/frame0-sync.py"
|
|
||||||
DEFAULT_ROOT="$REPO_ROOT/docs/design/wireframes"
|
|
||||||
|
|
||||||
DRY_RUN=false
|
|
||||||
FORCE=false
|
|
||||||
CATEGORY=""
|
|
||||||
WF_ROOT="$DEFAULT_ROOT"
|
|
||||||
|
|
||||||
# Parse arguments
|
|
||||||
while [[ $# -gt 0 ]]; do
|
|
||||||
case "$1" in
|
|
||||||
--dry-run) DRY_RUN=true; shift ;;
|
|
||||||
--force) FORCE=true; shift ;;
|
|
||||||
--category) CATEGORY="$2"; shift 2 ;;
|
|
||||||
--root) WF_ROOT="$2"; shift 2 ;;
|
|
||||||
-h|--help)
|
|
||||||
sed -n '/^# /p' "$0" | sed 's/^# //'
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*) echo "Unknown option: $1" >&2; exit 1 ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
if [[ ! -d "$WF_ROOT" ]]; then
|
|
||||||
echo "ERROR: Wireframes directory not found: $WF_ROOT" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Collect JSON files, optionally filtered by category subdirectory
|
|
||||||
mapfile -t JSON_FILES < <(
|
|
||||||
if [[ -n "$CATEGORY" ]]; then
|
|
||||||
find "$WF_ROOT/$CATEGORY" -name "*.json" ! -name ".*" | sort
|
|
||||||
else
|
|
||||||
find "$WF_ROOT" -name "*.json" ! -name ".*" | sort
|
|
||||||
fi
|
|
||||||
)
|
|
||||||
|
|
||||||
if [[ ${#JSON_FILES[@]} -eq 0 ]]; then
|
|
||||||
echo "No wireframe JSON files found."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Classify files into to-export and to-skip
|
|
||||||
TO_EXPORT=()
|
|
||||||
TO_SKIP=()
|
|
||||||
|
|
||||||
for json in "${JSON_FILES[@]}"; do
|
|
||||||
png="${json%.json}.png"
|
|
||||||
if $FORCE || [[ ! -f "$png" ]] || [[ "$json" -nt "$png" ]]; then
|
|
||||||
TO_EXPORT+=("$json")
|
|
||||||
else
|
|
||||||
TO_SKIP+=("$json")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Print manifest
|
|
||||||
if [[ ${#TO_EXPORT[@]} -gt 0 ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "Will export (${#TO_EXPORT[@]} files):"
|
|
||||||
for json in "${TO_EXPORT[@]}"; do
|
|
||||||
png="${json%.json}.png"
|
|
||||||
rel="${json#$REPO_ROOT/}"
|
|
||||||
if [[ ! -f "$png" ]]; then
|
|
||||||
status="new"
|
|
||||||
else
|
|
||||||
status="updated"
|
|
||||||
fi
|
|
||||||
printf " [%-7s] %s\n" "$status" "$rel"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo ""
|
|
||||||
echo "Nothing to export (all PNGs up to date)."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ${#TO_SKIP[@]} -gt 0 ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "Will skip (${#TO_SKIP[@]} files already up to date):"
|
|
||||||
for json in "${TO_SKIP[@]}"; do
|
|
||||||
rel="${json#$REPO_ROOT/}"
|
|
||||||
printf " [skip ] %s\n" "$rel"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $DRY_RUN; then
|
|
||||||
echo ""
|
|
||||||
echo "Dry run — no exports performed."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ${#TO_EXPORT[@]} -eq 0 ]]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
PASSED=0
|
|
||||||
FAILED=0
|
|
||||||
FAILED_FILES=()
|
|
||||||
|
|
||||||
TOTAL=${#TO_EXPORT[@]}
|
|
||||||
IDX=0
|
|
||||||
|
|
||||||
for json in "${TO_EXPORT[@]}"; do
|
|
||||||
IDX=$((IDX + 1))
|
|
||||||
png="${json%.json}.png"
|
|
||||||
rel="${json#$REPO_ROOT/}"
|
|
||||||
|
|
||||||
printf "[%d/%d] %s ... " "$IDX" "$TOTAL" "$rel"
|
|
||||||
|
|
||||||
output=$(python3 "$SYNC" export "$json" "$png" 2>/tmp/frame0-batch-err.txt)
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 0 ]]; then
|
|
||||||
size=$(echo "$output" | tail -1 | grep -oP '\(\K[^)]+' || true)
|
|
||||||
echo "ok $size"
|
|
||||||
PASSED=$((PASSED + 1))
|
|
||||||
else
|
|
||||||
echo "FAILED"
|
|
||||||
cat /tmp/frame0-batch-err.txt >&2
|
|
||||||
FAILED=$((FAILED + 1))
|
|
||||||
FAILED_FILES+=("$rel")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "$PASSED exported, $FAILED failed."
|
|
||||||
|
|
||||||
if [[ $FAILED -gt 0 ]]; then
|
|
||||||
echo ""
|
|
||||||
echo "Failed:" >&2
|
|
||||||
for f in "${FAILED_FILES[@]}"; do
|
|
||||||
echo " $f" >&2
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,414 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""Frame0 sync: push local JSON wireframes to Frame0, pull pages back.
|
|
||||||
|
|
||||||
Local JSON is source of truth. Frame0 is a renderer.
|
|
||||||
A mapping file tracks local_id <-> frame0_id across push/pull cycles.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
frame0-sync.py push <wireframe.json> [--port PORT]
|
|
||||||
frame0-sync.py pull <page-id|page-name> <output.json> [--port PORT]
|
|
||||||
frame0-sync.py export <wireframe.json> <output.png> [--port PORT] [--format MIME]
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import urllib.request
|
|
||||||
import urllib.error
|
|
||||||
|
|
||||||
DEFAULT_PORT = 58320
|
|
||||||
|
|
||||||
|
|
||||||
def api(port, command, args=None):
|
|
||||||
"""Execute a Frame0 API command. Returns the data field on success."""
|
|
||||||
url = f"http://localhost:{port}/execute_command"
|
|
||||||
payload = json.dumps({"command": command, "args": args or {}}).encode()
|
|
||||||
req = urllib.request.Request(url, data=payload, headers={"Content-Type": "application/json"})
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(req) as resp:
|
|
||||||
result = json.loads(resp.read())
|
|
||||||
except urllib.error.HTTPError as e:
|
|
||||||
body = e.read().decode()
|
|
||||||
print(f"ERROR: {command}: HTTP {e.code}: {body[:500]}", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
except urllib.error.URLError as e:
|
|
||||||
print(f"ERROR: Cannot connect to Frame0 on port {port}: {e}", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not result.get("success"):
|
|
||||||
print(f"ERROR: {command}: {result.get('error', 'unknown')}", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
return result.get("data")
|
|
||||||
|
|
||||||
|
|
||||||
# -- Mapping file management --------------------------------------------------
|
|
||||||
|
|
||||||
def mapping_path(wireframe_path):
|
|
||||||
"""Derive the idmap path from the wireframe JSON path."""
|
|
||||||
d = os.path.dirname(wireframe_path)
|
|
||||||
base = os.path.splitext(os.path.basename(wireframe_path))[0]
|
|
||||||
return os.path.join(d, f".{base}.idmap.json")
|
|
||||||
|
|
||||||
|
|
||||||
def load_mapping(wireframe_path):
|
|
||||||
p = mapping_path(wireframe_path)
|
|
||||||
if os.path.exists(p):
|
|
||||||
with open(p) as f:
|
|
||||||
return json.load(f)
|
|
||||||
return {"page_id": None, "shapes": {}, "connectors": {}}
|
|
||||||
|
|
||||||
|
|
||||||
def save_mapping(wireframe_path, mapping):
|
|
||||||
p = mapping_path(wireframe_path)
|
|
||||||
os.makedirs(os.path.dirname(p) or ".", exist_ok=True)
|
|
||||||
with open(p, "w") as f:
|
|
||||||
json.dump(mapping, f, indent=2)
|
|
||||||
f.write("\n")
|
|
||||||
|
|
||||||
|
|
||||||
# -- Push: local JSON -> Frame0 -----------------------------------------------
|
|
||||||
|
|
||||||
# Frame0 returns different type names from get vs what create accepts.
|
|
||||||
# Map internal types back to create-API types.
|
|
||||||
TYPE_TO_CREATE = {
|
|
||||||
"Box": "Rectangle",
|
|
||||||
"box": "Rectangle",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def topo_sort_shapes(shapes):
|
|
||||||
"""Sort shape IDs so parents come before children."""
|
|
||||||
order = []
|
|
||||||
visited = set()
|
|
||||||
|
|
||||||
def visit(sid):
|
|
||||||
if sid in visited:
|
|
||||||
return
|
|
||||||
visited.add(sid)
|
|
||||||
shape = shapes[sid]
|
|
||||||
parent = shape.get("parent")
|
|
||||||
if parent and parent in shapes:
|
|
||||||
visit(parent)
|
|
||||||
order.append(sid)
|
|
||||||
|
|
||||||
for sid in shapes:
|
|
||||||
visit(sid)
|
|
||||||
return order
|
|
||||||
|
|
||||||
|
|
||||||
def find_or_create_page(port, name, mapping):
|
|
||||||
"""Find existing page by mapping or name, or create a new one."""
|
|
||||||
# Try mapped page_id first
|
|
||||||
if mapping.get("page_id"):
|
|
||||||
try:
|
|
||||||
page = api(port, "page:get", {"pageId": mapping["page_id"]})
|
|
||||||
if page:
|
|
||||||
return mapping["page_id"]
|
|
||||||
except SystemExit:
|
|
||||||
pass # Page no longer exists, fall through
|
|
||||||
|
|
||||||
# Search by name in existing pages
|
|
||||||
doc = api(port, "doc:get", {"exportPages": True, "exportShapes": False})
|
|
||||||
if doc and "children" in doc:
|
|
||||||
for page in doc["children"]:
|
|
||||||
if page.get("name") == name:
|
|
||||||
return page["id"]
|
|
||||||
|
|
||||||
# Create new page
|
|
||||||
page = api(port, "page:add", {"pageProps": {"name": name}})
|
|
||||||
return page["id"]
|
|
||||||
|
|
||||||
|
|
||||||
def clear_page(port, page_id):
|
|
||||||
"""Delete all shapes on a page."""
|
|
||||||
page = api(port, "page:get", {"pageId": page_id, "exportShapes": True})
|
|
||||||
if not page or "children" not in page:
|
|
||||||
return
|
|
||||||
shape_ids = [s["id"] for s in page["children"]]
|
|
||||||
if shape_ids:
|
|
||||||
api(port, "edit:delete", {"shapeIdArray": shape_ids})
|
|
||||||
|
|
||||||
|
|
||||||
def push(wireframe_path, port):
|
|
||||||
"""Push local wireframe JSON to Frame0."""
|
|
||||||
with open(wireframe_path) as f:
|
|
||||||
wireframe = json.load(f)
|
|
||||||
|
|
||||||
name = wireframe.get("name", os.path.splitext(os.path.basename(wireframe_path))[0])
|
|
||||||
shapes = wireframe.get("shapes", {})
|
|
||||||
connectors = wireframe.get("connectors", {})
|
|
||||||
|
|
||||||
mapping = load_mapping(wireframe_path)
|
|
||||||
|
|
||||||
# Find or create page
|
|
||||||
page_id = find_or_create_page(port, name, mapping)
|
|
||||||
mapping["page_id"] = page_id
|
|
||||||
|
|
||||||
# Switch to page and clear it
|
|
||||||
api(port, "page:set-current-page", {"pageId": page_id})
|
|
||||||
clear_page(port, page_id)
|
|
||||||
|
|
||||||
# Reset ID mappings (shapes are recreated)
|
|
||||||
mapping["shapes"] = {}
|
|
||||||
mapping["connectors"] = {}
|
|
||||||
|
|
||||||
# Create shapes in dependency order
|
|
||||||
order = topo_sort_shapes(shapes)
|
|
||||||
for local_id in order:
|
|
||||||
shape = shapes[local_id]
|
|
||||||
raw_type = shape.get("type", "Rectangle")
|
|
||||||
shape_type = TYPE_TO_CREATE.get(raw_type, raw_type)
|
|
||||||
parent_local = shape.get("parent")
|
|
||||||
|
|
||||||
# Build shapeProps from everything except meta fields
|
|
||||||
meta_keys = {"type", "parent"}
|
|
||||||
props = {k: v for k, v in shape.items() if k not in meta_keys}
|
|
||||||
|
|
||||||
# Set name to local_id if not explicitly set
|
|
||||||
if "name" not in props:
|
|
||||||
props["name"] = local_id
|
|
||||||
|
|
||||||
create_args = {
|
|
||||||
"type": shape_type,
|
|
||||||
"shapeProps": props,
|
|
||||||
"convertColors": True,
|
|
||||||
}
|
|
||||||
|
|
||||||
# Resolve parent ID
|
|
||||||
if parent_local and parent_local in mapping["shapes"]:
|
|
||||||
create_args["parentId"] = mapping["shapes"][parent_local]
|
|
||||||
|
|
||||||
f0_id = api(port, "shape:create-shape", create_args)
|
|
||||||
mapping["shapes"][local_id] = f0_id
|
|
||||||
|
|
||||||
# Create connectors
|
|
||||||
for local_id, conn in connectors.items():
|
|
||||||
tail_local = conn.get("tailId")
|
|
||||||
head_local = conn.get("headId")
|
|
||||||
|
|
||||||
if tail_local not in mapping["shapes"] or head_local not in mapping["shapes"]:
|
|
||||||
print(f"WARNING: connector '{local_id}' references unknown shape, skipping", file=sys.stderr)
|
|
||||||
continue
|
|
||||||
|
|
||||||
meta_keys = {"tailId", "headId"}
|
|
||||||
props = {k: v for k, v in conn.items() if k not in meta_keys}
|
|
||||||
if "name" not in props:
|
|
||||||
props["name"] = local_id
|
|
||||||
|
|
||||||
f0_id = api(port, "shape:create-connector", {
|
|
||||||
"tailId": mapping["shapes"][tail_local],
|
|
||||||
"headId": mapping["shapes"][head_local],
|
|
||||||
"shapeProps": props,
|
|
||||||
"convertColors": True,
|
|
||||||
})
|
|
||||||
mapping["connectors"][local_id] = f0_id
|
|
||||||
|
|
||||||
# Fit to screen
|
|
||||||
api(port, "view:fit-to-screen")
|
|
||||||
|
|
||||||
save_mapping(wireframe_path, mapping)
|
|
||||||
total = len(mapping["shapes"]) + len(mapping["connectors"])
|
|
||||||
print(f"Pushed '{name}' to Frame0: {len(mapping['shapes'])} shapes, {len(mapping['connectors'])} connectors")
|
|
||||||
|
|
||||||
|
|
||||||
# -- Pull: Frame0 -> local JSON -----------------------------------------------
|
|
||||||
|
|
||||||
def pull(page_ref, output_path, port):
|
|
||||||
"""Pull a Frame0 page into local wireframe JSON."""
|
|
||||||
# Resolve page_ref: could be an ID or a name
|
|
||||||
page_id = None
|
|
||||||
doc = api(port, "doc:get", {"exportPages": True, "exportShapes": False})
|
|
||||||
if doc and "children" in doc:
|
|
||||||
for page in doc["children"]:
|
|
||||||
if page["id"] == page_ref or page.get("name") == page_ref:
|
|
||||||
page_id = page["id"]
|
|
||||||
page_name = page.get("name", page_ref)
|
|
||||||
break
|
|
||||||
|
|
||||||
if not page_id:
|
|
||||||
print(f"ERROR: Page not found: {page_ref}", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Load existing mapping for reverse lookup
|
|
||||||
mapping = load_mapping(output_path)
|
|
||||||
reverse_map = {v: k for k, v in mapping.get("shapes", {}).items()}
|
|
||||||
reverse_conn = {v: k for k, v in mapping.get("connectors", {}).items()}
|
|
||||||
|
|
||||||
# Get full page with shapes
|
|
||||||
page = api(port, "page:get", {"pageId": page_id, "exportShapes": True})
|
|
||||||
|
|
||||||
shapes = {}
|
|
||||||
connectors = {}
|
|
||||||
new_mapping = {"page_id": page_id, "shapes": {}, "connectors": {}}
|
|
||||||
auto_id_counter = [0]
|
|
||||||
|
|
||||||
def auto_id(f0_shape):
|
|
||||||
"""Generate a stable local ID from shape name or auto-number."""
|
|
||||||
# Prefer existing mapping
|
|
||||||
f0_id = f0_shape["id"]
|
|
||||||
if f0_id in reverse_map:
|
|
||||||
return reverse_map[f0_id]
|
|
||||||
# Use sanitized name
|
|
||||||
name = f0_shape.get("name", "")
|
|
||||||
if name:
|
|
||||||
sanitized = name.lower().replace(" ", "-").replace("_", "-")
|
|
||||||
if sanitized not in shapes:
|
|
||||||
return sanitized
|
|
||||||
# Fallback: auto-number
|
|
||||||
auto_id_counter[0] += 1
|
|
||||||
return f"s{auto_id_counter[0]:03d}"
|
|
||||||
|
|
||||||
def process_shape(f0_shape, parent_local_id=None):
|
|
||||||
f0_id = f0_shape["id"]
|
|
||||||
local_id = auto_id(f0_shape)
|
|
||||||
new_mapping["shapes"][local_id] = f0_id
|
|
||||||
|
|
||||||
# Extract shape properties — only strip structural keys that our
|
|
||||||
# ID mapping replaces. Everything else passes through as-is so the
|
|
||||||
# local JSON speaks Frame0's native vocabulary.
|
|
||||||
shape_type = f0_shape.get("type", "Box")
|
|
||||||
skip_keys = {"id", "type", "children", "pageId", "parentId"}
|
|
||||||
props = {k: v for k, v in f0_shape.items() if k not in skip_keys and v is not None}
|
|
||||||
|
|
||||||
entry = {"type": shape_type}
|
|
||||||
if parent_local_id:
|
|
||||||
entry["parent"] = parent_local_id
|
|
||||||
entry.update(props)
|
|
||||||
|
|
||||||
# Remove name if it matches local_id (redundant)
|
|
||||||
if entry.get("name") == local_id:
|
|
||||||
del entry["name"]
|
|
||||||
|
|
||||||
shapes[local_id] = entry
|
|
||||||
|
|
||||||
# Process children recursively
|
|
||||||
for child in f0_shape.get("children", []):
|
|
||||||
child_type = child.get("type", "")
|
|
||||||
if child_type == "Connector":
|
|
||||||
process_connector(child)
|
|
||||||
else:
|
|
||||||
process_shape(child, local_id)
|
|
||||||
|
|
||||||
def process_connector(f0_conn):
|
|
||||||
f0_id = f0_conn["id"]
|
|
||||||
local_id = reverse_conn.get(f0_id)
|
|
||||||
if not local_id:
|
|
||||||
auto_id_counter[0] += 1
|
|
||||||
local_id = f"c{auto_id_counter[0]:03d}"
|
|
||||||
|
|
||||||
new_mapping["connectors"][local_id] = f0_id
|
|
||||||
|
|
||||||
tail_f0 = f0_conn.get("tail", {}).get("id")
|
|
||||||
head_f0 = f0_conn.get("head", {}).get("id")
|
|
||||||
|
|
||||||
entry = {}
|
|
||||||
if tail_f0:
|
|
||||||
# Will be resolved after all shapes are processed
|
|
||||||
entry["_tailF0"] = tail_f0
|
|
||||||
if head_f0:
|
|
||||||
entry["_headF0"] = head_f0
|
|
||||||
|
|
||||||
skip_keys = {"id", "type", "children", "pageId", "tail", "head"}
|
|
||||||
props = {k: v for k, v in f0_conn.items() if k not in skip_keys and v is not None}
|
|
||||||
entry.update(props)
|
|
||||||
|
|
||||||
connectors[local_id] = entry
|
|
||||||
|
|
||||||
# Process all top-level shapes
|
|
||||||
for child in page.get("children", []):
|
|
||||||
child_type = child.get("type", "")
|
|
||||||
if child_type == "Connector":
|
|
||||||
process_connector(child)
|
|
||||||
else:
|
|
||||||
process_shape(child)
|
|
||||||
|
|
||||||
# Resolve connector references to local IDs
|
|
||||||
f0_to_local = {v: k for k, v in new_mapping["shapes"].items()}
|
|
||||||
for conn in connectors.values():
|
|
||||||
tail_f0 = conn.pop("_tailF0", None)
|
|
||||||
head_f0 = conn.pop("_headF0", None)
|
|
||||||
if tail_f0 and tail_f0 in f0_to_local:
|
|
||||||
conn["tailId"] = f0_to_local[tail_f0]
|
|
||||||
if head_f0 and head_f0 in f0_to_local:
|
|
||||||
conn["headId"] = f0_to_local[head_f0]
|
|
||||||
|
|
||||||
wireframe = {"name": page_name}
|
|
||||||
if shapes:
|
|
||||||
wireframe["shapes"] = shapes
|
|
||||||
if connectors:
|
|
||||||
wireframe["connectors"] = connectors
|
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
|
|
||||||
with open(output_path, "w") as f:
|
|
||||||
json.dump(wireframe, f, indent=2)
|
|
||||||
f.write("\n")
|
|
||||||
|
|
||||||
save_mapping(output_path, new_mapping)
|
|
||||||
print(f"Pulled '{page_name}' -> {output_path}: {len(shapes)} shapes, {len(connectors)} connectors")
|
|
||||||
|
|
||||||
|
|
||||||
# -- Export: push then export as image -----------------------------------------
|
|
||||||
|
|
||||||
def export_image(wireframe_path, output_path, port, fmt="image/png"):
|
|
||||||
"""Push wireframe to Frame0 and export the page as an image."""
|
|
||||||
import base64
|
|
||||||
|
|
||||||
# Push first to ensure Frame0 is up to date
|
|
||||||
push(wireframe_path, port)
|
|
||||||
|
|
||||||
mapping = load_mapping(wireframe_path)
|
|
||||||
page_id = mapping.get("page_id")
|
|
||||||
if not page_id:
|
|
||||||
print("ERROR: No page_id in mapping after push", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
image_b64 = api(port, "file:export-image", {
|
|
||||||
"pageId": page_id,
|
|
||||||
"format": fmt,
|
|
||||||
"fillBackground": True,
|
|
||||||
})
|
|
||||||
|
|
||||||
image_bytes = base64.b64decode(image_b64)
|
|
||||||
with open(output_path, "wb") as f:
|
|
||||||
f.write(image_bytes)
|
|
||||||
|
|
||||||
print(f"Exported: {output_path} ({len(image_bytes) // 1024}KB)")
|
|
||||||
|
|
||||||
|
|
||||||
# -- CLI -----------------------------------------------------------------------
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description="Sync wireframe JSON with Frame0")
|
|
||||||
parser.add_argument("--port", type=int, default=int(os.environ.get("FRAME0_PORT", DEFAULT_PORT)))
|
|
||||||
sub = parser.add_subparsers(dest="command")
|
|
||||||
|
|
||||||
p_push = sub.add_parser("push", help="Push local JSON to Frame0")
|
|
||||||
p_push.add_argument("wireframe", help="Path to wireframe .json file")
|
|
||||||
|
|
||||||
p_pull = sub.add_parser("pull", help="Pull Frame0 page to local JSON")
|
|
||||||
p_pull.add_argument("page", help="Page ID or page name")
|
|
||||||
p_pull.add_argument("output", help="Output .json path")
|
|
||||||
|
|
||||||
p_export = sub.add_parser("export", help="Push and export as image")
|
|
||||||
p_export.add_argument("wireframe", help="Path to wireframe .json file")
|
|
||||||
p_export.add_argument("output", help="Output image path (e.g. wireframe.png)")
|
|
||||||
p_export.add_argument("--format", default="image/png",
|
|
||||||
help="Export MIME type (default: image/png)")
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
if args.command == "push":
|
|
||||||
push(args.wireframe, args.port)
|
|
||||||
elif args.command == "pull":
|
|
||||||
pull(args.page, args.output, args.port)
|
|
||||||
elif args.command == "export":
|
|
||||||
export_image(args.wireframe, args.output, args.port, args.format)
|
|
||||||
else:
|
|
||||||
parser.print_help()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -14,29 +14,40 @@ Follow these conventions whenever you create a commit in this repository. These
|
|||||||
|
|
||||||
## Message style
|
## Message style
|
||||||
|
|
||||||
- **First line:** imperative mood, ≤ 70 characters. Examples: `add sidecar PTY scaffold`, `fix IPC reconnect after app reload`, `update CLI exit-code contract`.
|
This repo uses [Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/) (per [D-37](../../../governance/decisions/process.md#d-37)).
|
||||||
|
|
||||||
|
- **First line:** `type(scope): imperative subject`, ≤ 72 characters **including** the prefix. Examples: `feat(settings): add Appearance font picker (T-460)`, `fix(ipc): reconnect after app reload`, `docs(readme): drop brittle version line`.
|
||||||
|
- **Type:** one of `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `chore`. Use `feat`/`fix` for user-visible behavior; `chore` for bookkeeping (`chore(plan)` is the convention for pql ticket housekeeping). Append `!` after the scope for a breaking change (`feat(ipc)!: …`).
|
||||||
|
- **Scope (optional but preferred):** the subsystem the change lives in — `settings`, `vim`, `pty`, `git`, `plan`, etc. Lower-case, no spaces.
|
||||||
|
- **Ticket ref:** keep a trailing `(T-NNN)` on the subject when the work has a ticket — `feat(settings): category rail + navigation (T-447)`.
|
||||||
- **Body (optional):** wrap at ~72 chars. Explain the *why* — the reason this change exists. The diff already shows the *what*; don't restate it in prose.
|
- **Body (optional):** wrap at ~72 chars. Explain the *why* — the reason this change exists. The diff already shows the *what*; don't restate it in prose.
|
||||||
- **No emojis.** Anywhere.
|
- **No emojis.** Anywhere.
|
||||||
- **Don't prefix with types** like `feat:` or `fix:` — this repo isn't Conventional Commits. (The Python-era clide under `legacy/` used Conventional Commits; the Flutter rebuild at the repo root does not.)
|
|
||||||
- **Don't reference the current task or flow** (`for the v2.0 milestone`, `used by the canvas panel`) — that context belongs in the PR description and rots as the repo evolves.
|
- **Don't reference the current task or flow** (`for the v2.0 milestone`, `used by the canvas panel`) — that context belongs in the PR description and rots as the repo evolves.
|
||||||
- **Naming:** the project is `clide`. The Flutter desktop app lives at the repo root; the Go sidecar/CLI binary is `clide`. The supporter project is `pql` (referenced, not part of this repo). The archived Python implementation lives under `legacy/`.
|
- **Naming:** the project is `clide`. The Flutter desktop app lives at the repo root; the `clide` CLI is a thin C client (`native/clide-cli/`). The supporter project is `pql` (referenced, not part of this repo). The archived Python implementation lives under `legacy/`.
|
||||||
|
|
||||||
## Logically-separated commits
|
## Logically-separated commits
|
||||||
|
|
||||||
Default to **one logical change per commit**, even when a lot of work lands in the tree at once. When there's a pile of uncommitted or untracked files:
|
Default to **one logical change per commit**, even when a lot of work lands in the tree at once. When there's a pile of uncommitted or untracked files:
|
||||||
|
|
||||||
1. **Read `git status` + `git diff` first** — never stage the whole tree blind.
|
1. **Read `git status` + `git diff` first** — never stage the whole tree blind.
|
||||||
2. **Group by concern**, not by file location. Typical concerns to separate:
|
2. **Triage: session vs pre-existing.** Separate changes you made in this
|
||||||
|
session from changes that were already dirty (or that a concurrent session
|
||||||
|
is producing — this worktree can host several Claude sessions at once).
|
||||||
|
Check the conversation history — if you didn't touch a file, it's not yours
|
||||||
|
to stage. After grouping your own commits, surface any remaining modified
|
||||||
|
or untracked files to the user and ask whether they belong in a commit.
|
||||||
|
Never silently skip or silently include changes that aren't yours.
|
||||||
|
3. **Group by concern**, not by file location. Typical concerns to separate:
|
||||||
- **Bookkeeping** — `.gitignore`, editor/IDE config, lockfiles, `go.sum` / `pubspec.lock` updates.
|
- **Bookkeeping** — `.gitignore`, editor/IDE config, lockfiles, `go.sum` / `pubspec.lock` updates.
|
||||||
- **Documentation** — `README.md`, `CLAUDE.md`, ADRs under `docs/ADRs/`, design notes under `docs/`.
|
- **Documentation** — `README.md`, `CLAUDE.md`, D-records under `governance/`, design notes under `docs/`.
|
||||||
- **General-purpose tooling / skills** — things that aren't project-specific (reusable skills, shared scripts).
|
- **General-purpose tooling / skills** — things that aren't project-specific (reusable skills, shared scripts).
|
||||||
- **Project-specific conventions** — this repo's own rules.
|
- **Project-specific conventions** — this repo's own rules.
|
||||||
- **Feature or subsystem** — one cohesive change per commit; a sidecar change and an app change for the same feature can land together, but two unrelated features should split.
|
- **Feature or subsystem** — one cohesive change per commit; a CLI change and an app change for the same feature can land together, but two unrelated features should split.
|
||||||
- **Layer changes** — Flutter app, sidecar CLI, sidecar daemon, IPC server, pql wrapper, canvas driver, git panel — separate concerns; prefer separate commits when the changes are independent.
|
- **Layer changes** — Flutter app, `clide` CLI (`native/clide-cli/`), IPC server, pql wrapper, canvas driver, git panel — separate concerns; prefer separate commits when the changes are independent.
|
||||||
3. **Sequence the commits** so each one is cleanly scoped, but don't obsess about whether each intermediate commit "works" — for scaffolding PRs it's fine if the full picture only snaps together at the end.
|
4. **Sequence the commits** so each one is cleanly scoped, but don't obsess about whether each intermediate commit "works" — for scaffolding PRs it's fine if the full picture only snaps together at the end.
|
||||||
4. **Prefer many small focused commits over one large mixed one** — a reviewer can read, revert, or cherry-pick a focused commit; they can't do any of those to a blob.
|
5. **Prefer many small focused commits over one large mixed one** — a reviewer can read, revert, or cherry-pick a focused commit; they can't do any of those to a blob.
|
||||||
5. **Use `git add <specific paths>`** — never `git add -A` or `git add .` when splitting, or you'll sweep in the next commit's work by accident.
|
6. **Use `git add <specific paths>`** — never `git add -A` or `git add .` when splitting, or you'll sweep in the next commit's work by accident.
|
||||||
6. **Verify between commits** with `git status` and `git log -1` to confirm the split landed as intended.
|
7. **Verify between commits** with `git status` and `git log -1` to confirm the split landed as intended.
|
||||||
|
|
||||||
Corollary: if a commit's subject line needs the word "and" to be accurate, it probably should have been two commits.
|
Corollary: if a commit's subject line needs the word "and" to be accurate, it probably should have been two commits.
|
||||||
|
|
||||||
@@ -55,7 +66,7 @@ Entries should be short imperative phrases that describe user-facing impact —
|
|||||||
|
|
||||||
### Be concise — this is the rule, not a suggestion
|
### Be concise — this is the rule, not a suggestion
|
||||||
|
|
||||||
CHANGELOG entries must be **one or two short sentences**. Hard cap: **60 words per bullet** (enforced by `ci/changelog_gate.sh`). Aim for 30 or under; if you can't say it in one line wrapped at ~75 columns, you're writing the wrong document.
|
CHANGELOG entries must be **one or two short sentences**. Hard cap: **60 words per bullet**, enforced by the pre-push gate — verify before committing with `make changelog-gate` (run the `make` target, not the script it wraps). Aim for 30 or under; if you can't say it in one line wrapped at ~75 columns, you're writing the wrong document.
|
||||||
|
|
||||||
The CHANGELOG is read by humans scanning for what changed between two versions. It is **not** the place for the rationale, the probe results, the implementation detail, the behavior-change deep dive, or the "see also" cross-references. Those belong in:
|
The CHANGELOG is read by humans scanning for what changed between two versions. It is **not** the place for the rationale, the probe results, the implementation detail, the behavior-change deep dive, or the "see also" cross-references. Those belong in:
|
||||||
|
|
||||||
@@ -93,9 +104,11 @@ Cutting a release is its own commit. In a single commit:
|
|||||||
1. Move all entries from `## [Unreleased]` under a new heading `## [X.Y.Z] — YYYY-MM-DD`.
|
1. Move all entries from `## [Unreleased]` under a new heading `## [X.Y.Z] — YYYY-MM-DD`.
|
||||||
2. Leave an empty `## [Unreleased]` section at the top with its subsection skeleton ready.
|
2. Leave an empty `## [Unreleased]` section at the top with its subsection skeleton ready.
|
||||||
3. Bump `pubspec.yaml` `version:` to `X.Y.Z` (drop the `-dev` suffix for the tag; re-add it on the next development commit if desired).
|
3. Bump `pubspec.yaml` `version:` to `X.Y.Z` (drop the `-dev` suffix for the tag; re-add it on the next development commit if desired).
|
||||||
4. Commit subject: `release vX.Y.Z`.
|
4. Run `make gen-build-info` so `assets/licenses.yaml` `self.version:` re-syncs from pubspec (it's auto-rewritten by every build but commit the fresh state). Stage the resulting diff alongside step 3.
|
||||||
|
5. Commit subject: `release vX.Y.Z`.
|
||||||
|
6. **Tag it.** After the commit lands, run `make release` — it verifies the version/changelog/clean-tree invariants, runs the full gate, and creates the annotated `vX.Y.Z` tag. Then `git push origin main --follow-tags` to publish the commit and the tag together. **Every released version must have a matching `git tag`** — a CHANGELOG heading without a tag is an incomplete release (T-393: tagging had silently lapsed from v2.2.0 through v2.8.0). Don't hand-roll the tag; `make release` keeps the tag, gate, and version in lockstep. If you tag by hand, use an annotated tag (`git tag -a vX.Y.Z -m "clide vX.Y.Z"`); never push a release commit without its tag.
|
||||||
|
|
||||||
`pubspec.yaml` is the single source of truth for the version — the Makefile reads it for ldflag stamping of the sidecar binary, and the Flutter app reads it for build info. Bumping `pubspec.yaml` and the changelog out of sync is the mistake this rule prevents.
|
`pubspec.yaml` is the single source of truth for the version. Every `make` build/run/test target regenerates `lib/src/build_info.g.dart` (gitignored) and rewrites `assets/licenses.yaml` `self.version:` from it — so the Flutter app sees the current version everywhere without manual sync. Bumping `pubspec.yaml` and the changelog out of sync is the mistake this rule prevents.
|
||||||
|
|
||||||
## Attribution trailer
|
## Attribution trailer
|
||||||
|
|
||||||
@@ -107,32 +120,39 @@ Co-Authored-By: Claude <noreply@anthropic.com>
|
|||||||
|
|
||||||
The model-identifier variant produced by the Claude Code harness (e.g. `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>`) is also accepted — don't rewrite it if the harness emits that form.
|
The model-identifier variant produced by the Claude Code harness (e.g. `Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>`) is also accepted — don't rewrite it if the harness emits that form.
|
||||||
|
|
||||||
## HEREDOC discipline
|
## Message-file discipline
|
||||||
|
|
||||||
Pass commit messages via HEREDOC so multi-line formatting survives:
|
Pass commit messages via a message file so multi-line formatting survives
|
||||||
|
and the command stays inside the permission allowlist (command substitution
|
||||||
|
defeats the `git commit` prefix match and triggers permission prompts):
|
||||||
|
|
||||||
|
1. Write the full message to a file in `/tmp` (never inside `.git/` — that
|
||||||
|
directory is git's own state) using the Write tool.
|
||||||
|
2. Commit with it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git commit -m "$(cat <<'EOF'
|
git commit -F /tmp/commit-msg.txt
|
||||||
short imperative summary
|
|
||||||
|
|
||||||
Optional longer body explaining why this change was needed,
|
|
||||||
wrapped at about 72 characters.
|
|
||||||
|
|
||||||
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
||||||
EOF
|
|
||||||
)"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Never pass multi-line messages via `-m "line1\nline2"` or multiple `-m` flags — Git's behavior differs between shells and quoting regimes and the trailer can end up in the wrong place.
|
Fallback only: the HEREDOC-in-substitution form
|
||||||
|
(`git commit -m "$(cat <<'EOF' … EOF)"`) works but prompts for permission —
|
||||||
|
use it only when writing a file is impossible. Never pass multi-line messages
|
||||||
|
via `-m "line1\nline2"` or multiple `-m` flags — Git's behavior differs
|
||||||
|
between shells and quoting regimes and the trailer can end up in the wrong
|
||||||
|
place.
|
||||||
|
|
||||||
## What not to commit
|
## What not to commit
|
||||||
|
|
||||||
- `.env` and any `*.env.local` — see `.gitignore`.
|
- `.env` and any `*.env.local` — see `.gitignore`.
|
||||||
- `.claude/settings.local.json` — user-specific Claude Code settings, ignored.
|
- `.claude/settings.local.json` — user-specific Claude Code settings, ignored.
|
||||||
- Build artefacts: `sidecar/bin/`, `sidecar/dist/`, `build/` (Flutter output), `app/.dart_tool/` — gitignored.
|
- Build artefacts: `/build/` (Flutter output), `/.dart_tool/` — gitignored.
|
||||||
- SQLite index files (`*.sqlite`, `*.sqlite-wal`, `*.sqlite-shm`, `*.db`) — caches generated against local repos; must never land here. Gitignored defensively.
|
- SQLite index files (`*.sqlite`, `*.sqlite-wal`, `*.sqlite-shm`, `*.db`) — caches generated against local repos; must never land here. Gitignored defensively.
|
||||||
- Coverage / test output (`*.out`, `coverage.*`, `*.test`) — gitignored.
|
- Coverage / test output (`*.out`, `coverage.*`, `*.test`) — gitignored.
|
||||||
|
|
||||||
|
## Don't hand-manage `.pql/changelog`
|
||||||
|
|
||||||
|
The pre-commit hook exports the pql ticket DB and **auto-stages `.pql/changelog/` on every commit**. Don't `git add .pql/changelog` yourself and don't write a dedicated "flush the export" commit — just make your normal commit and the hook sweeps the ticket state in. The only thing to remember: a turn that files/changes a ticket but makes **zero commits** never fires the hook, so the change won't persist (and a later branch switch can drop it). The fix is simply to make a commit — you don't need to touch `.pql/changelog`.
|
||||||
|
|
||||||
## Safety reminders (reinforced from the global Claude Code protocol)
|
## Safety reminders (reinforced from the global Claude Code protocol)
|
||||||
|
|
||||||
- **Never** `--no-verify`. If a pre-commit hook fails, fix the underlying issue and create a new commit.
|
- **Never** `--no-verify`. If a pre-commit hook fails, fix the underlying issue and create a new commit.
|
||||||
|
|||||||
@@ -1,193 +0,0 @@
|
|||||||
---
|
|
||||||
name: pql
|
|
||||||
description: >
|
|
||||||
Query and plan against a markdown vault via the pql CLI. Two surfaces:
|
|
||||||
(1) structural queries — frontmatter, wikilinks, tags, headings, Bases,
|
|
||||||
DSL — use when the user asks about vault contents ("which notes…", "find
|
|
||||||
where…", "what tags", "who links to X", "run a Base", "query the vault");
|
|
||||||
(2) planning — decision records, tickets, project status — use when the
|
|
||||||
user asks about decisions, tickets, work items, or project planning
|
|
||||||
("sync decisions", "create a ticket", "what's the plan status", "show
|
|
||||||
D-5", "board"). Requires `pql` on PATH. JSON on stdout; exit 2 = zero
|
|
||||||
matches (not an error).
|
|
||||||
---
|
|
||||||
|
|
||||||
# pql — vault queries + project planning
|
|
||||||
|
|
||||||
`pql` indexes a vault into SQLite and exposes structural queries plus a
|
|
||||||
planning layer for decision records and tickets. One binary, two surfaces.
|
|
||||||
|
|
||||||
## Precondition
|
|
||||||
|
|
||||||
```bash
|
|
||||||
command -v pql
|
|
||||||
```
|
|
||||||
|
|
||||||
If absent, tell the user to install from
|
|
||||||
https://github.com/postmeridiem/pql/releases/latest. Don't install it
|
|
||||||
yourself. Don't fall back to grep unless the user explicitly asks.
|
|
||||||
|
|
||||||
## First touch: learn the vault
|
|
||||||
|
|
||||||
```bash
|
|
||||||
pql schema
|
|
||||||
```
|
|
||||||
|
|
||||||
Returns one row per frontmatter key with observed types and file counts.
|
|
||||||
Run once per session before writing queries.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Surface 1: Vault queries
|
|
||||||
|
|
||||||
### Subcommands
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---|---|
|
|
||||||
| `pql files [glob]` | List indexed files; optional glob filter |
|
|
||||||
| `pql tags [--sort count]` | Distinct tags with counts |
|
|
||||||
| `pql backlinks <path>` | Files linking TO a path |
|
|
||||||
| `pql outlinks <path>` | Links FROM a file |
|
|
||||||
| `pql meta <path>` | Frontmatter + tags + outlinks + headings for one file |
|
|
||||||
| `pql schema` | Typed frontmatter schema |
|
|
||||||
| `pql base <name>` | Execute an Obsidian .base file |
|
|
||||||
| `pql shell` | Interactive REPL (indexes once, then query per line) |
|
|
||||||
| `pql query "<DSL>"` | SQL-derived DSL for complex queries |
|
|
||||||
| `pql doctor` | Resolved vault/config/DB/index state |
|
|
||||||
|
|
||||||
### DSL examples
|
|
||||||
|
|
||||||
```sql
|
|
||||||
SELECT name, fm.date WHERE fm.type = 'meeting' ORDER BY fm.date DESC LIMIT 10
|
|
||||||
SELECT path WHERE 'project' IN tags ORDER BY path
|
|
||||||
SELECT name, fm.prior_job WHERE fm.type = 'council-member' ORDER BY name
|
|
||||||
```
|
|
||||||
|
|
||||||
Use `--file q.pql` or `--stdin` for long queries. Don't interpolate vault
|
|
||||||
content into the command line.
|
|
||||||
|
|
||||||
### Query cookbook
|
|
||||||
|
|
||||||
- **Files in folder** → `pql files 'sessions/*'`
|
|
||||||
- **Top tags** → `pql tags --sort count --limit 20`
|
|
||||||
- **What links to X?** → `pql backlinks members/vaasa/persona.md`
|
|
||||||
- **Date range** → `pql query "SELECT name, fm.date WHERE fm.date BETWEEN '2024-01-01' AND '2024-12-31'"`
|
|
||||||
- **Run a Base** → `pql base council-sessions`
|
|
||||||
- **Inspect one file** → `pql meta members/vaasa/persona.md --pretty`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Surface 2: Planning (decisions + tickets)
|
|
||||||
|
|
||||||
Planning state lives in `<vault>/.pql/pql.db` (user-authored state, not a
|
|
||||||
cache). Decision records come from `decisions/*.md`; tickets are
|
|
||||||
SQLite-native.
|
|
||||||
|
|
||||||
### Decision subcommands
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---|---|
|
|
||||||
| `pql decisions sync` | Parse decisions/*.md → upsert into pql.db |
|
|
||||||
| `pql decisions validate` | Dry-run parse; exits non-zero on malformed records |
|
|
||||||
| `pql decisions claim <D\|Q\|R> <domain> "title"` | Print next available ID |
|
|
||||||
| `pql decisions list [--type X] [--domain X] [--status X]` | List decisions |
|
|
||||||
| `pql decisions show <id> [--with-refs] [--with-tickets]` | Show with joins |
|
|
||||||
| `pql decisions coverage` | Confirmed decisions without tickets |
|
|
||||||
| `pql decisions refs <id>` | Cross-references involving a decision |
|
|
||||||
|
|
||||||
Always `pql decisions sync` before querying if decisions/*.md may have changed.
|
|
||||||
|
|
||||||
### Ticket subcommands
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---|---|
|
|
||||||
| `pql ticket new <type> "title" [--decision D-NNN] [--priority P]` | Create (emits T-NNN) |
|
|
||||||
| `pql ticket list [--status S] [--team T] [--assigned A] [--label L]` | List with filters |
|
|
||||||
| `pql ticket show <id> [--with-context] [--with-blockers]` | Show with joins (context = ancestors + decisions + children) |
|
|
||||||
| `pql ticket status <id[,id,...]> <new-status>` | Transition (batch via comma-separated IDs) |
|
|
||||||
| `pql ticket assign <id> <agent>` | Set assignee |
|
|
||||||
| `pql ticket block <id> --by <other>` | Add blocker |
|
|
||||||
| `pql ticket unblock <id> --from <other>` | Remove blocker |
|
|
||||||
| `pql ticket team <id> <team>` | Set team |
|
|
||||||
| `pql ticket label <id> add\|rm <label>` | Manage labels |
|
|
||||||
| `pql ticket board [--team T]` | Kanban board view |
|
|
||||||
|
|
||||||
Ticket types: initiative, epic, story, task, bug.
|
|
||||||
Status flow: backlog → ready → in_progress → review → done (also cancelled).
|
|
||||||
|
|
||||||
### Plan subcommands
|
|
||||||
|
|
||||||
| Command | Purpose |
|
|
||||||
|---|---|
|
|
||||||
| `pql plan status` | Dashboard: decision counts, open Qs, ticket summary, coverage gaps |
|
|
||||||
| `pql plan export [--to FILE]` | Snapshot planning state to JSON (default: `pql-plan.json`) |
|
|
||||||
| `pql plan import [--from FILE]` | Restore planning state from a JSON snapshot |
|
|
||||||
|
|
||||||
### Versioning planning state
|
|
||||||
|
|
||||||
Planning state lives in `pql.db` (gitignored). To version it in git,
|
|
||||||
use `pql plan export` to write a committed JSON snapshot. pql does NOT
|
|
||||||
do this automatically — the user decides when and how to trigger it:
|
|
||||||
|
|
||||||
- Pre-push hook: `.githooks/pre-push` calls `pql plan export && git add pql-plan.json`
|
|
||||||
- Sprint close: a skill or script exports + commits on milestone
|
|
||||||
- Manual: run `pql plan export` before committing when state changed
|
|
||||||
|
|
||||||
On a fresh clone, `pql plan import` restores from the snapshot.
|
|
||||||
|
|
||||||
### Planning cookbook
|
|
||||||
|
|
||||||
- **Sync and list confirmed** → `pql decisions sync && pql decisions list --type confirmed`
|
|
||||||
- **Show with refs** → `pql decisions show D-5 --with-refs --pretty`
|
|
||||||
- **Create ticket** → `pql ticket new task "implement X" --decision D-5`
|
|
||||||
- **Batch close** → `pql ticket status T-1,T-2,T-3 done`
|
|
||||||
- **Coverage gaps** → `pql decisions coverage`
|
|
||||||
- **Dashboard** → `pql plan status --pretty`
|
|
||||||
- **Snapshot for git** → `pql plan export`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Output contract (both surfaces)
|
|
||||||
|
|
||||||
- **stdout:** JSON array (default); `--jsonl` for one object/line; `--pretty`; `--limit N`.
|
|
||||||
- **stderr:** JSON diagnostics `{"level":"…","code":"pql.<phase>.<kind>","msg":"…"}`.
|
|
||||||
- **Exit codes:**
|
|
||||||
- `0` — success, ≥1 result
|
|
||||||
- `2` — zero matches (not an error — say "no matches", not "failed")
|
|
||||||
- `64` — bad flag
|
|
||||||
- `65` — parse/compile error (pass stderr back)
|
|
||||||
- `66` — vault/config not found
|
|
||||||
- `69` — unavailable
|
|
||||||
- `70` — internal error
|
|
||||||
|
|
||||||
## Anti-patterns
|
|
||||||
|
|
||||||
- Don't pipe to `jq` for simple projections — use `--limit`, `--pretty`, `--jsonl`.
|
|
||||||
- Don't chain `pql files` + `pql meta` — one `pql query` with WHERE.
|
|
||||||
- Don't parse errors — pass stderr diagnostics back directly.
|
|
||||||
- Don't forget `pql decisions sync` before querying decisions.
|
|
||||||
- Don't try to install or upgrade pql — instruct the user if missing.
|
|
||||||
|
|
||||||
## When NOT to use
|
|
||||||
|
|
||||||
- **Body text search** → `grep`/`rg`.
|
|
||||||
- **Reading file contents** → `Read` tool.
|
|
||||||
- **Code structure** → tree-sitter / LSP.
|
|
||||||
- **Modifying vault files** → `Write`/`Edit`. pql doesn't write to vault content.
|
|
||||||
|
|
||||||
## Permissions
|
|
||||||
|
|
||||||
The consuming project's `.claude/settings.json` should allow:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"permissions": {
|
|
||||||
"allow": ["Bash(pql)", "Bash(pql *)"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Updating the skill
|
|
||||||
|
|
||||||
`pql skill status` reports drift. `pql skill install` writes/updates;
|
|
||||||
`--force` overrides hand-edits. `pql doctor` also surfaces skill state.
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
---
|
|
||||||
name: skill-create
|
|
||||||
description: >
|
|
||||||
Guidance for creating effective Claude Code skills (.skill packages).
|
|
||||||
Use when the user wants to create, build, design, or iterate on a skill —
|
|
||||||
including writing SKILL.md files, bundling scripts/references/assets,
|
|
||||||
initializing new skills, packaging skills, or improving existing ones.
|
|
||||||
Triggers on requests like "create a skill", "make a new skill",
|
|
||||||
"build a skill for X", "package this skill", or "improve my skill".
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
# Skill Creator
|
|
||||||
|
|
||||||
## About Skills
|
|
||||||
|
|
||||||
Skills are modular, self-contained packages that extend Claude's capabilities
|
|
||||||
by providing specialized knowledge, workflows, and tools. They transform Claude
|
|
||||||
from a general-purpose agent into a specialized agent equipped with procedural
|
|
||||||
knowledge that no model can fully possess.
|
|
||||||
|
|
||||||
### What Skills Provide
|
|
||||||
|
|
||||||
- **Specialized workflows** — Multi-step procedures for specific domains
|
|
||||||
- **Tool integrations** — Instructions for working with specific file formats or APIs
|
|
||||||
- **Domain expertise** — Company-specific knowledge, schemas, business logic
|
|
||||||
- **Bundled resources** — Scripts, references, and assets for complex and repetitive tasks
|
|
||||||
|
|
||||||
## Core Principles
|
|
||||||
|
|
||||||
### Concise is Key
|
|
||||||
|
|
||||||
The context window is a public good. Skills share it with everything else Claude
|
|
||||||
needs: system prompt, conversation history, other skills' metadata, and the
|
|
||||||
actual user request.
|
|
||||||
|
|
||||||
Default assumption: Claude is already very smart. Only add context Claude doesn't
|
|
||||||
already have. Challenge each piece of information: "Does Claude really need this
|
|
||||||
explanation?" and "Does this paragraph justify its token cost?"
|
|
||||||
|
|
||||||
Prefer concise examples over verbose explanations.
|
|
||||||
|
|
||||||
### Set Appropriate Degrees of Freedom
|
|
||||||
|
|
||||||
Match specificity to the task's fragility and variability:
|
|
||||||
|
|
||||||
- **High freedom** (text-based instructions): Multiple approaches valid, decisions
|
|
||||||
depend on context, heuristics guide the approach.
|
|
||||||
- **Medium freedom** (pseudocode or scripts with parameters): Preferred pattern
|
|
||||||
exists, some variation acceptable, configuration affects behavior.
|
|
||||||
- **Low freedom** (specific scripts, few parameters): Operations are fragile and
|
|
||||||
error-prone, consistency is critical, specific sequence must be followed.
|
|
||||||
|
|
||||||
Think of Claude as exploring a path: a narrow bridge with cliffs needs specific
|
|
||||||
guardrails (low freedom), while an open field allows many routes (high freedom).
|
|
||||||
|
|
||||||
## Anatomy of a Skill
|
|
||||||
|
|
||||||
```
|
|
||||||
skill-name/
|
|
||||||
├── SKILL.md (required)
|
|
||||||
│ ├── YAML frontmatter metadata (required)
|
|
||||||
│ │ ├── name: (required)
|
|
||||||
│ │ ├── description: (required)
|
|
||||||
│ │ └── compatibility: (optional, rarely needed)
|
|
||||||
│ └── Markdown instructions (required)
|
|
||||||
└── Bundled Resources (optional)
|
|
||||||
├── scripts/ - Executable code (Python/Bash/etc.)
|
|
||||||
├── references/ - Documentation loaded into context as needed
|
|
||||||
└── assets/ - Files used in output (templates, icons, fonts, etc.)
|
|
||||||
```
|
|
||||||
|
|
||||||
### SKILL.md (required)
|
|
||||||
|
|
||||||
- **Frontmatter (YAML)**: `name` and `description` fields (required). Only these
|
|
||||||
are read by Claude to determine when the skill triggers — be clear and
|
|
||||||
comprehensive. The `compatibility` field is for environment requirements but
|
|
||||||
most skills don't need it.
|
|
||||||
- **Body (Markdown)**: Instructions and guidance. Only loaded AFTER the skill
|
|
||||||
triggers.
|
|
||||||
|
|
||||||
### Bundled Resources (optional)
|
|
||||||
|
|
||||||
**Scripts (`scripts/`)** — Executable code for tasks requiring deterministic
|
|
||||||
reliability or that are repeatedly rewritten.
|
|
||||||
|
|
||||||
**References (`references/`)** — Documentation loaded as needed into context.
|
|
||||||
Keep SKILL.md lean; move detailed reference material, schemas, and examples here.
|
|
||||||
If files are large (>10k words), include grep search patterns in SKILL.md.
|
|
||||||
|
|
||||||
**Assets (`assets/`)** — Files used in output, not loaded into context (templates,
|
|
||||||
images, icons, boilerplate code, fonts).
|
|
||||||
|
|
||||||
### What to NOT Include
|
|
||||||
|
|
||||||
Do NOT create extraneous files like README.md, INSTALLATION_GUIDE.md,
|
|
||||||
QUICK_REFERENCE.md, CHANGELOG.md, etc. The skill should only contain information
|
|
||||||
needed for an AI agent to do the job.
|
|
||||||
|
|
||||||
## Progressive Disclosure
|
|
||||||
|
|
||||||
Skills use a three-level loading system:
|
|
||||||
|
|
||||||
1. **Metadata** (name + description) — Always in context (~100 words)
|
|
||||||
2. **SKILL.md body** — When skill triggers (<5k words)
|
|
||||||
3. **Bundled resources** — As needed (unlimited; scripts can run without reading)
|
|
||||||
|
|
||||||
Keep SKILL.md body under 500 lines. Split content into separate files when
|
|
||||||
approaching this limit. Reference split files from SKILL.md with clear
|
|
||||||
descriptions of when to read them.
|
|
||||||
|
|
||||||
### Disclosure Patterns
|
|
||||||
|
|
||||||
**Pattern 1: High-level guide with references** — Keep overview in SKILL.md,
|
|
||||||
link to detail files loaded only when needed.
|
|
||||||
|
|
||||||
**Pattern 2: Domain-specific organization** — Organize content by domain
|
|
||||||
(e.g., `references/finance.md`, `references/sales.md`) so only relevant content
|
|
||||||
is loaded.
|
|
||||||
|
|
||||||
**Pattern 3: Conditional details** — Show basic content, link to advanced
|
|
||||||
content loaded only when the user needs those features.
|
|
||||||
|
|
||||||
Guidelines:
|
|
||||||
- Avoid deeply nested references — keep one level deep from SKILL.md
|
|
||||||
- Structure longer reference files with a table of contents at the top
|
|
||||||
|
|
||||||
## Skill Creation Process
|
|
||||||
|
|
||||||
Follow these steps in order, skipping only with clear reason:
|
|
||||||
|
|
||||||
### Step 1: Understand the Skill with Concrete Examples
|
|
||||||
|
|
||||||
Skip only when usage patterns are already clearly understood.
|
|
||||||
|
|
||||||
Ask the user for concrete examples of how the skill will be used:
|
|
||||||
- "What functionality should the skill support?"
|
|
||||||
- "Can you give some examples of how this skill would be used?"
|
|
||||||
- "What would a user say that should trigger this skill?"
|
|
||||||
|
|
||||||
Avoid overwhelming users — start with the most important questions.
|
|
||||||
|
|
||||||
### Step 2: Plan the Reusable Skill Contents
|
|
||||||
|
|
||||||
Analyze each example by considering how to execute from scratch and identifying
|
|
||||||
what scripts, references, and assets would help with repeated execution.
|
|
||||||
|
|
||||||
Establish a list of reusable resources: scripts, references, and assets.
|
|
||||||
|
|
||||||
### Step 3: Initialize the Skill
|
|
||||||
|
|
||||||
Create the skill directory manually:
|
|
||||||
|
|
||||||
```
|
|
||||||
mkdir -p <output-directory>/<skill-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
Then create `SKILL.md` with frontmatter and body. Add `scripts/`, `references/`,
|
|
||||||
and `assets/` subdirectories only as needed.
|
|
||||||
|
|
||||||
Skip if iterating on an existing skill.
|
|
||||||
|
|
||||||
### Step 4: Edit the Skill
|
|
||||||
|
|
||||||
Remember the skill is for another Claude instance to use. Include beneficial,
|
|
||||||
non-obvious information.
|
|
||||||
|
|
||||||
For design patterns, consult:
|
|
||||||
- `references/workflows.md` — Sequential workflows and conditional logic
|
|
||||||
- `references/output-patterns.md` — Template and example patterns
|
|
||||||
|
|
||||||
**Implementation order:**
|
|
||||||
1. Start with reusable resources (`scripts/`, `references/`, `assets/`)
|
|
||||||
2. Test added scripts by running them
|
|
||||||
3. Delete unused example files from initialization
|
|
||||||
4. Update SKILL.md
|
|
||||||
|
|
||||||
**Writing guidelines:** Always use imperative/infinitive form.
|
|
||||||
|
|
||||||
**Frontmatter:**
|
|
||||||
- `name`: The skill name — use **domain-action** naming: `{domain}-{action}`.
|
|
||||||
The domain is the system/area the skill operates on, the action is what it does.
|
|
||||||
Examples: `pr-review`, `sprint-plan`, `docs-search`, `git-commit`, `debt-scan`.
|
|
||||||
Multi-action wrappers (like `ticket`) can use the domain name alone.
|
|
||||||
The directory name must match the `name` field.
|
|
||||||
- `description`: Primary triggering mechanism. Include what the skill does AND
|
|
||||||
specific triggers/contexts. All "when to use" info goes here (not in body).
|
|
||||||
|
|
||||||
**Body:** Instructions for using the skill and its bundled resources.
|
|
||||||
|
|
||||||
### Step 5: Validate the Skill
|
|
||||||
|
|
||||||
Check the skill manually:
|
|
||||||
- Frontmatter has `name` and `description`
|
|
||||||
- SKILL.md body is under 500 lines
|
|
||||||
- No extraneous files (README.md, CHANGELOG.md, etc.)
|
|
||||||
- Scripts are executable and tested
|
|
||||||
- References are referenced from SKILL.md
|
|
||||||
|
|
||||||
### Step 6: Iterate
|
|
||||||
|
|
||||||
After real usage, notice struggles or inefficiencies, identify needed updates,
|
|
||||||
implement changes, and test again.
|
|
||||||
@@ -6,9 +6,10 @@ description: >
|
|||||||
lifecycle, theme loading, or native platform code. Also use when
|
lifecycle, theme loading, or native platform code. Also use when
|
||||||
the user says "run testmode", "test the app", "smoke test", or
|
the user says "run testmode", "test the app", "smoke test", or
|
||||||
"verify the build". Triggers on changes to: lib/kernel/src/toolchain.dart,
|
"verify the build". Triggers on changes to: lib/kernel/src/toolchain.dart,
|
||||||
lib/src/daemon/dispatcher.dart, lib/src/ipc/, lib/extension/,
|
lib/src/daemon/dispatcher.dart, lib/src/ipc/, lib/src/pty/,
|
||||||
lib/kernel/src/theme/, lib/builtin/*/src/extension.dart,
|
lib/builtin/terminal/, lib/extension/, lib/kernel/src/theme/,
|
||||||
linux/CMakeLists.txt, macos/, Makefile (run targets), lib/main.dart.
|
lib/builtin/*/src/extension.dart, linux/CMakeLists.txt, macos/,
|
||||||
|
Makefile (run targets), lib/main.dart.
|
||||||
---
|
---
|
||||||
|
|
||||||
# Testmode harness
|
# Testmode harness
|
||||||
@@ -26,6 +27,7 @@ make run-testmode # all categories, 60s timeout
|
|||||||
make run-testmode TESTMODE_CATEGORY=toolchain
|
make run-testmode TESTMODE_CATEGORY=toolchain
|
||||||
make run-testmode TESTMODE_CATEGORY=ipc
|
make run-testmode TESTMODE_CATEGORY=ipc
|
||||||
make run-testmode TESTMODE_CATEGORY=extensions
|
make run-testmode TESTMODE_CATEGORY=extensions
|
||||||
|
make run-testmode TESTMODE_CATEGORY=terminal
|
||||||
make run-testmode TESTMODE_TIMEOUT=120 # longer timeout for slow builds
|
make run-testmode TESTMODE_TIMEOUT=120 # longer timeout for slow builds
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -47,6 +49,7 @@ Exit code is non-zero when any test fails. The Makefile verifies
|
|||||||
| IPC envelope, dispatcher, schema | `ipc` | Round-trip + error contract |
|
| IPC envelope, dispatcher, schema | `ipc` | Round-trip + error contract |
|
||||||
| Extension manifest, activate, contributions | `extensions` | Register + activate lifecycle |
|
| Extension manifest, activate, contributions | `extensions` | Register + activate lifecycle |
|
||||||
| Theme YAML, loader, palette | `extensions` | Theme parse is in this category |
|
| Theme YAML, loader, palette | `extensions` | Theme parse is in this category |
|
||||||
|
| PTY spawning, terminal pane, xterm wiring | `terminal` | Real PTY spawn + I/O round-trip |
|
||||||
| Platform config (CMakeLists, pbxproj, Makefile) | `all` | Full rebuild validates everything |
|
| Platform config (CMakeLists, pbxproj, Makefile) | `all` | Full rebuild validates everything |
|
||||||
| Any doubt | `all` | ~30s, cheap insurance |
|
| Any doubt | `all` | ~30s, cheap insurance |
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ This skill bundles four concerns that all surface in widget work:
|
|||||||
| Token selection per surface | [`references/surface.md`](references/surface.md) | Building a new widget or modifying an existing one — "which token does this need" |
|
| Token selection per surface | [`references/surface.md`](references/surface.md) | Building a new widget or modifying an existing one — "which token does this need" |
|
||||||
| Spacing, alignment, control layout | [`references/geometry.md`](references/geometry.md) | Building tab strips, list items, buttons, anything where icons sit next to text or padded edges |
|
| Spacing, alignment, control layout | [`references/geometry.md`](references/geometry.md) | Building tab strips, list items, buttons, anything where icons sit next to text or padded edges |
|
||||||
| Phosphor icon usage and codepoints | [`references/icons.md`](references/icons.md) | Adding or referencing an icon |
|
| Phosphor icon usage and codepoints | [`references/icons.md`](references/icons.md) | Adding or referencing an icon |
|
||||||
|
| Full Phosphor glyph table (1512, with codepoints) | [`references/phosphor-glyphs.md`](references/phosphor-glyphs.md) | Picking a specific glyph by name/look — find its codepoint, see if it's already defined |
|
||||||
|
|
||||||
Read the reference that matches the question. They cross-reference each
|
Read the reference that matches the question. They cross-reference each
|
||||||
other where relevant; you don't need to read all four.
|
other where relevant; you don't need to read all four.
|
||||||
@@ -35,8 +36,71 @@ These apply across every reference and every surface:
|
|||||||
- Never use `Material*` or `Cupertino*` widgets or color constants — clide
|
- Never use `Material*` or `Cupertino*` widgets or color constants — clide
|
||||||
is `WidgetsApp` only (D-7).
|
is `WidgetsApp` only (D-7).
|
||||||
- Use `ClideText` for themed text; never bare `Text` in production widgets.
|
- Use `ClideText` for themed text; never bare `Text` in production widgets.
|
||||||
- Typography: `clideFontMono` for code/paths/IDs, `clideFontCaption` for
|
- Typography sizes: `clideFontMono` for code/paths/IDs, `clideFontCaption` for
|
||||||
status/section headers, body inherits from `DefaultTextStyle`.
|
status/section headers, body inherits from `DefaultTextStyle`.
|
||||||
|
- Font *family* comes from the user-selectable facade, not a const: a
|
||||||
|
monospace surface uses `fontFamily: ClideSettings.fonts.monoOf(context)`
|
||||||
|
(and `fontFamilyFallback: clideMonoFamilyFallback`); the UI face is inherited
|
||||||
|
via the root `DefaultTextStyle`, or `ClideSettings.fonts.uiOf(context)` when a
|
||||||
|
widget must set it explicitly. `clideMonoFamily` / `clideUiFamily` are the
|
||||||
|
facade's defaults — don't read them directly in new widgets (D-101). Same
|
||||||
|
facade exposes `ClideSettings.theme.of(context)` and `.i18n.of(context)`.
|
||||||
|
- User-facing strings resolve through the catalog, never a hardcoded literal
|
||||||
|
(D-21/D-102): `ClideSettings.i18n.string(context, 'dotted.key', namespace:
|
||||||
|
<ext id or 'core'>, placeholder: '<English>')` (or `.interpolated` for
|
||||||
|
templated). Add the key→English to `assets/i18n/en_us/<namespace>.json`. The
|
||||||
|
`placeholder` is the English fallback; the extension's own id is its
|
||||||
|
namespace (framework chrome uses `core`). Contribution manifests carry
|
||||||
|
`titleKey`/`labelKey` for the same reason.
|
||||||
|
|
||||||
|
## Localization & string length (D-21/D-102)
|
||||||
|
|
||||||
|
- **Config / layout.** Catalogs are bundled assets at
|
||||||
|
`assets/i18n/<locale>/<namespace>.json` — the locale is a *directory*
|
||||||
|
(`en_us`, `nl_nl`, `nl_be`, `en_eu`, …); a new language is a new folder of the
|
||||||
|
same namespace files. The active language is `app.locale` (Settings →
|
||||||
|
Appearance → Language), applied live by `root_shell` via `i18n.setLocale`;
|
||||||
|
add the `Locale` to `availableLocales` in `main.dart` and a folder under
|
||||||
|
`assets/i18n/`. `en_US` is default; `nl_NL` ships.
|
||||||
|
- **Design for length variation.** Translations are not the same width — Dutch
|
||||||
|
runs ~20% longer than English, German more. So **never hard-size a surface to
|
||||||
|
its English label.** Tight surfaces (status-bar items, chips, buttons, tab
|
||||||
|
titles, menu items) must tolerate ~30% growth: let them wrap, ellipsis, or
|
||||||
|
`Flexible`/`Expanded`, not a fixed width tuned to English. When you add or
|
||||||
|
translate a label, sanity-check the length delta on those tight surfaces (an
|
||||||
|
`*.semantics` label is screen-reader-only, so its length never deforms
|
||||||
|
layout). A quick audit: compare `len(nl)/len(en)` per key and eyeball the
|
||||||
|
short-but-grew cases on real (non-semantics) surfaces.
|
||||||
|
|
||||||
|
## Conversation-panel cards (T-305)
|
||||||
|
|
||||||
|
The Claude conversation stream has **three** card categories. They are NOT one
|
||||||
|
shared wrapper widget — each is its own widget; they only share the spacing
|
||||||
|
constants in `lib/widgets/src/clide_card_metrics.dart` (`kClideCardGap`,
|
||||||
|
`kClideCardRadius`, `kClideCardHeaderPadH/V`, `kClideCardCounterSlotWidth`) so
|
||||||
|
the stream reads as one rhythm. Change spacing there, not per-card.
|
||||||
|
|
||||||
|
1. **Dialog cards** — `ConversationCard` with a speaker **side stripe** (you /
|
||||||
|
claude / agent). Prose/attribution; not collapsible.
|
||||||
|
2. **Simple cards** — a single item shown fully open, never collapses (e.g. the
|
||||||
|
image card). Standalone display; no chevron, no status chrome.
|
||||||
|
3. **Collapsibles** — `ClideCollapserCard` (`lib/widgets/`). Every tool use is
|
||||||
|
one, over a list of `1..N` inner item cards (a single tool = a 1-item list;
|
||||||
|
there is no separate single-card path). Rules:
|
||||||
|
- Whole card toggles; chevron hard against the **left** edge, the status tick
|
||||||
|
(spinner/check/cross) hard against the **right** edge, the count in a
|
||||||
|
fixed-width slot just inboard of it.
|
||||||
|
- `color` drives the border + chevron/label tint (per-instance fidelity).
|
||||||
|
- Collapsed ticker echoes the run's **last content line** as the title +
|
||||||
|
count + aggregate status (computed by the caller, bubbled up from items).
|
||||||
|
- Inner item cards are content + their **own** per-item status; they pass
|
||||||
|
`margin: EdgeInsets.zero`-ish (a bottom margin matching the canvas) so the
|
||||||
|
collapser pads the inner canvas **evenly on all sides** — never let an
|
||||||
|
inner card jam under the header or against a frame edge.
|
||||||
|
|
||||||
|
Do NOT pull a dialog card's stripe or a simple card's config into the collapser,
|
||||||
|
and do NOT nest collapsers — inside a run, tools render as the bare inner content
|
||||||
|
card (`_ConversationTurn(collapseTools: false)`).
|
||||||
|
|
||||||
## Anti-patterns (cross-cutting)
|
## Anti-patterns (cross-cutting)
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,26 @@ Container(
|
|||||||
- Eyeballing alignment without working back from a target margin in
|
- Eyeballing alignment without working back from a target margin in
|
||||||
pixels. The math matters; see "uniform inner spacing".
|
pixels. The math matters; see "uniform inner spacing".
|
||||||
|
|
||||||
|
## Ultrawide — clide is an IDE, assume wide screens (T-239)
|
||||||
|
|
||||||
|
The default `flutter_test` surface is 800px, but clide runs on 3440/5120
|
||||||
|
ultrawide constantly. Two consequences:
|
||||||
|
|
||||||
|
- **Right-align with `Expanded`, not a `Spacer` that fights a flex sibling.**
|
||||||
|
A `Row[ left…, Flexible(flex:1), Spacer(), right… ]` splits the free space
|
||||||
|
between the loose flex item and the `Spacer` 50/50 — so the right group is
|
||||||
|
pushed only *half* the free space. The drift is **proportional to width**:
|
||||||
|
invisible at 800–1200px, ~1500px adrift at 3440px. To pin a right group to
|
||||||
|
the edge regardless of width, put the left group in `Expanded(Row[...])`
|
||||||
|
(it absorbs *all* free space; flex items flex within it) and let the right
|
||||||
|
group trail at intrinsic width. See `StatusbarHost` in `lib/app.dart`.
|
||||||
|
- **Test layout at ultrawide, not just the default surface.** Width-sensitive
|
||||||
|
bugs hide at 800px. Drive the surface with `tester.view.physicalSize` —
|
||||||
|
a wide `SizedBox` under the default 800px surface is CLAMPED to 800, so it
|
||||||
|
doesn't actually test wide. Pattern in `test/app_statusbar_test.dart`
|
||||||
|
(`pumpAt`): set `view.physicalSize`, assert key positions at a normal AND an
|
||||||
|
ultrawide width. Audit tracked in T-241.
|
||||||
|
|
||||||
## Testing alignment
|
## Testing alignment
|
||||||
|
|
||||||
When iterating on a control's spacing:
|
When iterating on a control's spacing:
|
||||||
|
|||||||
@@ -5,28 +5,31 @@
|
|||||||
The app bundles Phosphor Icons (v2.0.8, MIT) as TTF fonts at
|
The app bundles Phosphor Icons (v2.0.8, MIT) as TTF fonts at
|
||||||
`assets/fonts/phosphor/` (regular, bold, fill weights).
|
`assets/fonts/phosphor/` (regular, bold, fill weights).
|
||||||
|
|
||||||
**Codepoint reference:** `assets/fonts/phosphor/codepoints.csv` — full
|
**Glyph reference:** [`phosphor-glyphs.md`](phosphor-glyphs.md) — the full
|
||||||
mapping of all 1512 icon codepoints to kebab-case and PascalCase
|
1512-glyph table (codepoint · kebab name · Pascal name). Grep it for the exact
|
||||||
names. Read this file to look up any icon by name or codepoint.
|
kebab name; **all 1512 are available** — no per-icon wiring (T-314).
|
||||||
|
|
||||||
### Adding an icon
|
|
||||||
|
|
||||||
Find the codepoint in `codepoints.csv`, then add a `static const`
|
|
||||||
entry to `PhosphorIcons` in `lib/widgets/src/icons/phosphor.dart`:
|
|
||||||
|
|
||||||
```dart
|
|
||||||
static const arrowClockwise = PhosphorIconPainter(0xe036);
|
|
||||||
```
|
|
||||||
|
|
||||||
Only add icons we actually use — don't bulk-import the full set.
|
|
||||||
|
|
||||||
### Using an icon
|
### Using an icon
|
||||||
|
|
||||||
|
Reference a glyph by its **exact kebab-case name** — no codepoints in feature
|
||||||
|
code; the label→codepoint table lives only in the generated
|
||||||
|
`lib/widgets/src/icons/phosphor_glyphs.g.dart`:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
ClideIcon(PhosphorIcons.arrowClockwise, size: 13)
|
ClideIcon(PhosphorIcons.byName('arrow-clockwise'), size: 13)
|
||||||
```
|
```
|
||||||
|
|
||||||
Or as a `TabContribution` icon field: `icon: PhosphorIcons.lightbulb`.
|
Or as a `TabContribution` icon field: `icon: PhosphorIcons.byName('lightbulb')`.
|
||||||
|
|
||||||
|
- An **unknown name** is a bug — it degrades to the `placeholder` error box so
|
||||||
|
the mistake is visible. `phosphor_glyphs_test` asserts every `byName('…')`
|
||||||
|
literal in `lib/` resolves, recovering the typo check a const would give.
|
||||||
|
- For an **intentional blank** that still reserves the icon's box (alignment),
|
||||||
|
use `const EmptyIconPainter()` — *not* a missing name.
|
||||||
|
- Regenerate the map after a font bump: `dart run tool/gen_phosphor_glyphs.dart`.
|
||||||
|
|
||||||
|
**Bold weight:** pass `family: 'Phosphor-Bold'` to `PhosphorIconPainter`.
|
||||||
|
**Fill weight:** `family: 'Phosphor-Fill'`.
|
||||||
|
|
||||||
**Bold weight:** pass `family: 'Phosphor-Bold'` to `PhosphorIconPainter`.
|
**Bold weight:** pass `family: 'Phosphor-Bold'` to `PhosphorIconPainter`.
|
||||||
**Fill weight:** `family: 'Phosphor-Fill'`.
|
**Fill weight:** `family: 'Phosphor-Fill'`.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -112,9 +112,37 @@ tooltip → tooltipBackground / tooltipForeground / tooltipBorder
|
|||||||
dropdown → dropdownBackground / dropdownForeground / dropdownBorder
|
dropdown → dropdownBackground / dropdownForeground / dropdownBorder
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Settings & grouped lists — sectioned cards
|
||||||
|
|
||||||
|
Settings surfaces and any long grouped list (e.g. the Claude config lists)
|
||||||
|
read as **sectioned cards**, not bare rows floating on the panel. Each logical
|
||||||
|
group gets its own card; the small-caps section label (+ optional count) sits
|
||||||
|
just **above** the card.
|
||||||
|
|
||||||
|
```
|
||||||
|
panel bg → panelBackground (#20202C)
|
||||||
|
card surface → surface (#242838) fill + dividerColor/border (1px), ~6px corners
|
||||||
|
section head → sidebarSectionHeader (small-caps), with the count muted to its right
|
||||||
|
control inset → inputs INSIDE a card recede to panelBackground, so they still
|
||||||
|
read as fields against the elevated card
|
||||||
|
```
|
||||||
|
|
||||||
|
- **One card per group** — a settings table, each config list. The card's
|
||||||
|
elevated fill + border do the visual separation; don't rely on spacing alone.
|
||||||
|
- **Field row inside a card:** label (`globalForeground`) + help
|
||||||
|
(`globalTextMuted`) + the control right-aligned, with the per-field scope tag
|
||||||
|
in the far-right column.
|
||||||
|
- **Scroll, don't cram:** when stacked cards exceed the modal/pane viewport, the
|
||||||
|
pane scrolls vertically (sticky header, scrolling body) — prefer that over
|
||||||
|
shrinking content to fit one screen.
|
||||||
|
- Pattern reference: the settings wireframes under
|
||||||
|
`docs/design/wireframes/settings/` (T-302).
|
||||||
|
|
||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- `globalBackground` for panel fill → use `panelBackground`
|
- `globalBackground` for panel fill → use `panelBackground`
|
||||||
|
- Bare settings rows on the panel where a group of them should be one card →
|
||||||
|
see "Settings & grouped lists".
|
||||||
- `listItemHoverBackground` in sidebar → use `sidebarItemHover`
|
- `listItemHoverBackground` in sidebar → use `sidebarItemHover`
|
||||||
- Tab active bg = `panelBackground` → use `panelHeader` (elevated chrome)
|
- Tab active bg = `panelBackground` → use `panelHeader` (elevated chrome)
|
||||||
- Tab active border = `globalFocus` → use `panelActiveBorder`
|
- Tab active border = `globalFocus` → use `panelActiveBorder`
|
||||||
|
|||||||
@@ -62,6 +62,36 @@ types, priority levels) should NOT add tokens to `SurfaceTokens`. Instead:
|
|||||||
This keeps the core token surface lean and lets each extension own its
|
This keeps the core token surface lean and lets each extension own its
|
||||||
palette. The pattern scales to any extension needing domain colors.
|
palette. The pattern scales to any extension needing domain colors.
|
||||||
|
|
||||||
|
## Named themes are user contracts — never retune their palette (D-69)
|
||||||
|
|
||||||
|
A bundled theme that ships under a recognisable name (`clide`, `midnight`,
|
||||||
|
`paper`, `terminal`, `catppuccin-*`, …) is a **user contract**. Its palette —
|
||||||
|
including syntax tokens, status colours, and `borderHi` — **MUST NOT be
|
||||||
|
retuned to pass a contrast gate**. Users pick Catppuccin because it looks like
|
||||||
|
Catppuccin; quietly darkening a swatch to clear WCAG changes what they signed
|
||||||
|
up for. Don't "fix" the artist's vision.
|
||||||
|
|
||||||
|
When a theme fails the contrast gate ([D-22](../../../governance/decisions/accessibility.md)),
|
||||||
|
the fix is **a sibling `-hc` (high-contrast) theme**, not an edit to the
|
||||||
|
faithful one (D-69):
|
||||||
|
|
||||||
|
- Keep `foo.yaml` pixel-faithful to the source palette.
|
||||||
|
- Add `foo-hc.yaml` — same silhouette, but muted text / status chips / syntax
|
||||||
|
tokens / focus border bumped to clear the strict (`extendedPairs`) gate. Only
|
||||||
|
`-hc`/`-cb` variants are held to the extended set; base themes pass the
|
||||||
|
baseline (`canonicalPairs`) only.
|
||||||
|
- Register both in `main.dart` `_loadBundledThemes` **and** the bundled list in
|
||||||
|
`test/a11y/contrast_test.dart`.
|
||||||
|
|
||||||
|
Mechanics: `canonicalPairs` (baseline, every theme) vs `extendedPairs`
|
||||||
|
(strict, `-hc`/`-cb` only) live in `lib/kernel/src/theme/contrast.dart`. If a
|
||||||
|
faithful palette is so soft it can't clear even the *baseline* chrome pairs,
|
||||||
|
that's a design call — surface it, don't silently retune. (Catppuccin Latte
|
||||||
|
hit exactly this on two chrome pairs.)
|
||||||
|
|
||||||
|
This is the same split VS Code ships: `Default Dark+` plus a separate
|
||||||
|
`Default High Contrast`.
|
||||||
|
|
||||||
## Where to look in the codebase
|
## Where to look in the codebase
|
||||||
|
|
||||||
- Full token list: `lib/kernel/src/theme/tokens.dart`
|
- Full token list: `lib/kernel/src/theme/tokens.dart`
|
||||||
|
|||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate the Phosphor glyph reference page for the ui-design skill.
|
||||||
|
|
||||||
|
Mirrors `assets/fonts/phosphor/codepoints.csv` (the full bundled glyph set)
|
||||||
|
into a readable, greppable markdown table at
|
||||||
|
`.claude/skills/ui-design/references/phosphor-glyphs.md`.
|
||||||
|
|
||||||
|
That table is also the source of truth for the `kPhosphorGlyphs` map — after
|
||||||
|
regenerating it, re-run `dart run tool/gen_phosphor_glyphs.dart` so
|
||||||
|
`lib/widgets/src/icons/phosphor_glyphs.g.dart` stays in sync.
|
||||||
|
|
||||||
|
Run from the repo root: python3 .claude/skills/ui-design/scripts/gen-phosphor-glyphs.py
|
||||||
|
"""
|
||||||
|
import csv
|
||||||
|
import pathlib
|
||||||
|
|
||||||
|
ROOT = pathlib.Path(__file__).resolve().parents[4]
|
||||||
|
CSV = ROOT / "assets/fonts/phosphor/codepoints.csv"
|
||||||
|
OUT = ROOT / ".claude/skills/ui-design/references/phosphor-glyphs.md"
|
||||||
|
|
||||||
|
rows = list(csv.DictReader(CSV.open()))
|
||||||
|
|
||||||
|
lines = [
|
||||||
|
"---",
|
||||||
|
"name: phosphor-glyphs",
|
||||||
|
"type: reference",
|
||||||
|
"tags: [icons, phosphor, ui-design]",
|
||||||
|
"---",
|
||||||
|
"",
|
||||||
|
"# Phosphor glyphs — full reference (v2.0.8)",
|
||||||
|
"",
|
||||||
|
f"All **{len(rows)}** glyphs bundled in clide's Phosphor font "
|
||||||
|
"(`assets/fonts/phosphor/`, MIT). Generated from "
|
||||||
|
"`assets/fonts/phosphor/codepoints.csv` — **do not hand-edit**; regenerate with "
|
||||||
|
"`python3 .claude/skills/ui-design/scripts/gen-phosphor-glyphs.py`, then re-run "
|
||||||
|
"`dart run tool/gen_phosphor_glyphs.dart` (this table is the source for the "
|
||||||
|
"generated `kPhosphorGlyphs` map).",
|
||||||
|
"",
|
||||||
|
"Every glyph is available in code via `PhosphorIcons.byName('<kebab-name>')` "
|
||||||
|
"(T-314) — e.g. `ClideIcon(PhosphorIcons.byName('folder'), size: 13)`. Raw "
|
||||||
|
"codepoints never appear in feature code; they live only in the generated map. "
|
||||||
|
"An unknown name renders the `placeholder` glyph, and `phosphor_glyphs_test` "
|
||||||
|
"asserts every `byName('…')` literal in `lib/` resolves.",
|
||||||
|
"",
|
||||||
|
"| Codepoint | Name (kebab) | Pascal |",
|
||||||
|
"|---|---|---|",
|
||||||
|
]
|
||||||
|
for r in rows:
|
||||||
|
lines.append(f"| `{r['codepoint']}` | {r['name']} | {r['pascal_name']} |")
|
||||||
|
|
||||||
|
OUT.write_text("\n".join(lines) + "\n")
|
||||||
|
print(f"wrote {OUT.relative_to(ROOT)} — {len(rows)} glyphs")
|
||||||
@@ -4,7 +4,8 @@ description: >
|
|||||||
Surface the best batch of tickets to pick up next from pql. Walks the
|
Surface the best batch of tickets to pick up next from pql. Walks the
|
||||||
initiative/epic tree, filters to unblocked work, refines context via
|
initiative/epic tree, filters to unblocked work, refines context via
|
||||||
parallel agents (or `pql ticket refine` for empty descriptions), and
|
parallel agents (or `pql ticket refine` for empty descriptions), and
|
||||||
optionally activates the batch on a fresh branch. Use when the user
|
optionally activates the batch (directly on main — no topic branch by
|
||||||
|
default). Use when the user
|
||||||
says "what's next", "next batch", "pick up work", or invokes
|
says "what's next", "next batch", "pick up work", or invokes
|
||||||
/whats-next. NOT triggered by "what should we work on" in a design
|
/whats-next. NOT triggered by "what should we work on" in a design
|
||||||
context — that's a discussion, not a batch selection.
|
context — that's a discussion, not a batch selection.
|
||||||
@@ -18,7 +19,8 @@ Dependency-driven batch selection against pql. Three steps:
|
|||||||
batch selection → refinement review → batch activation.
|
batch selection → refinement review → batch activation.
|
||||||
|
|
||||||
Pql is the single source of truth for tickets and decisions in this repo
|
Pql is the single source of truth for tickets and decisions in this repo
|
||||||
(see [pql skill](../pql/SKILL.md) and [`decisions/README.md`](../../../decisions/README.md)). Always run from the repo root.
|
(see the pql skill — user scope, installed via `pql init` — and
|
||||||
|
[`governance/README.md`](../../../governance/README.md)). Always run from the repo root.
|
||||||
|
|
||||||
## Step 0: Sync state
|
## Step 0: Sync state
|
||||||
|
|
||||||
@@ -50,24 +52,36 @@ user which area to advance.
|
|||||||
|
|
||||||
### 1b. Build the work landscape
|
### 1b. Build the work landscape
|
||||||
|
|
||||||
For each candidate epic or initiative, expand its children:
|
For each candidate epic or initiative, read its full descendant subtree
|
||||||
|
(nested, with the direct parent in `ancestors`) — one call, no client-side
|
||||||
|
flattening (pql ≥ 1.6.0):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pql ticket show <id> --with-children --pretty
|
pql ticket show <id> --tree --pretty # add --depth N to cap levels
|
||||||
```
|
```
|
||||||
|
|
||||||
Collect every leaf ticket (story/task/bug) underneath. Deduplicate.
|
This replaces the old `--with-children` + hand-rolled status summaries.
|
||||||
|
|
||||||
### 1c. Filter to unblocked tickets
|
### 1c. Filter to unblocked, actionable leaves
|
||||||
|
|
||||||
For each leaf with status `ready` or `backlog`, check blockers:
|
Don't walk blockers per ticket — pql does it. Compose the `list` filters
|
||||||
|
(pql ≥ 1.6.0): `--leaf` (no children), `--unblocked` (every blocker is
|
||||||
|
`done`/`cancelled`), and `--status` (since `--leaf`/`--unblocked` are
|
||||||
|
structure/blocker-state only and would otherwise include `done` leaves):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pql ticket show <id> --with-blockers --pretty
|
pql ticket list --under <epic-id> --leaf --unblocked --status backlog --pretty
|
||||||
```
|
```
|
||||||
|
|
||||||
A ticket is **unblocked** if every blocker is `done` or `cancelled`.
|
`--status` takes a SINGLE value (not a comma list — `backlog,ready` matches
|
||||||
Drop the rest.
|
nothing and silently returns `[]`). The repo is almost all `backlog`; if a
|
||||||
|
team uses `ready`, run it a second time with `--status ready`.
|
||||||
|
|
||||||
|
That returns exactly the actionable, unblocked leaves under the epic — the
|
||||||
|
multi-result complement to `pql plan whatsnext` (which now also skips blocked
|
||||||
|
tickets, for the single best pick). Note `--unblocked` only means no *ticket*
|
||||||
|
blocker is open; a ticket "blocked on upstream" in prose (e.g. T-158) still
|
||||||
|
shows — read the description before batching.
|
||||||
|
|
||||||
### 1d. Rank and group
|
### 1d. Rank and group
|
||||||
|
|
||||||
@@ -146,8 +160,8 @@ Agent({
|
|||||||
|
|
||||||
Your job:
|
Your job:
|
||||||
1. Run `pql decisions show <decision_ref> --with-refs --pretty` and
|
1. Run `pql decisions show <decision_ref> --with-refs --pretty` and
|
||||||
read the linked D/Q-record in decisions/<domain>.md.
|
read the linked D/Q-record in governance/decisions/<domain>.md.
|
||||||
2. Grep decisions/questions-*.md for related Q-records.
|
2. Grep governance/questions/<domain>.md for related Q-records.
|
||||||
3. Verify referenced files, classes, and APIs actually exist in the
|
3. Verify referenced files, classes, and APIs actually exist in the
|
||||||
current tree (Read/Grep). Flag dangling references.
|
current tree (Read/Grep). Flag dangling references.
|
||||||
4. Cross-check against CLAUDE.md guardrails (single process, CLI-first,
|
4. Cross-check against CLAUDE.md guardrails (single process, CLI-first,
|
||||||
@@ -166,12 +180,18 @@ Run all agents in parallel (single message, multiple Agent tool calls).
|
|||||||
|
|
||||||
For each ticket that came back GAPS, surface ambiguities to the user
|
For each ticket that came back GAPS, surface ambiguities to the user
|
||||||
via AskUserQuestion. After the user resolves, append the resolution to
|
via AskUserQuestion. After the user resolves, append the resolution to
|
||||||
the ticket via pql:
|
the ticket with `pql ticket append` (pql ≥ 1.6.0) — it appends
|
||||||
|
blank-line-separated WITHOUT round-tripping the existing description, so
|
||||||
|
there's no JSON-splicing or read-modify-write:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pql ticket refine write T-NN '{"description":"<existing body>\n\n---\nRefinement: <resolution>"}'
|
pql ticket append T-NN "Refinement (<date>): <resolution>"
|
||||||
|
# longer notes: pql ticket append T-NN --file note.md (or --stdin)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
(Use `append`, not `refine write` — the latter replaces the whole
|
||||||
|
description from a JSON patch and forces you to re-send the existing body.)
|
||||||
|
|
||||||
If a gap really requires a new D-record (architectural choice, not just
|
If a gap really requires a new D-record (architectural choice, not just
|
||||||
detail), flag it. Ask whether to write the D-record now (`pql decisions
|
detail), flag it. Ask whether to write the D-record now (`pql decisions
|
||||||
claim D <domain> "title"` then author the markdown) or defer with a note
|
claim D <domain> "title"` then author the markdown) or defer with a note
|
||||||
@@ -199,11 +219,22 @@ Batch transition (comma-separated IDs):
|
|||||||
pql ticket status T-1,T-2,T-3 in_progress
|
pql ticket status T-1,T-2,T-3 in_progress
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Then make sure it persists.** Ticket mutations (status here, and any
|
||||||
|
`ticket new` in Step 2) land only in the gitignored `.pql/pql.db`. The
|
||||||
|
pre-commit hook runs `pql plan export --stage` automatically — the changelog
|
||||||
|
is exported and staged on every commit, so never hand-run the export or
|
||||||
|
`git add .pql/changelog`. The rule is simpler: the turn must land at least
|
||||||
|
one commit (through the git-commit skill). A ticket-only turn with no commit
|
||||||
|
leaves the mutations in `pql.db` only, and the post-checkout/post-merge hooks
|
||||||
|
rebuild that DB from the committed changelog on the next branch switch —
|
||||||
|
silently dropping them. See the pql skill's "Versioning planning state"
|
||||||
|
section for the full mechanics.
|
||||||
|
|
||||||
### 3b. Branch? Default no.
|
### 3b. Branch? Default no.
|
||||||
|
|
||||||
Solo-dev flow on this repo — work lands directly on `main` (see recent
|
Solo-dev flow on this repo — work lands directly on `main` (see recent
|
||||||
`git log`). Don't create a topic branch unless the user explicitly asks.
|
`git log`). Don't create a topic branch unless the user explicitly asks.
|
||||||
If they do, plain `git checkout -b` is fine; there is no `gh` CLI.
|
If they do, plain `git checkout -b` is fine.
|
||||||
|
|
||||||
### 3c. Spawn implementation agents (optional)
|
### 3c. Spawn implementation agents (optional)
|
||||||
|
|
||||||
@@ -232,9 +263,13 @@ End with a tight summary:
|
|||||||
## Anti-patterns
|
## Anti-patterns
|
||||||
|
|
||||||
- Don't skip Step 0 — stale `pql.db` makes the rest of the skill lie.
|
- Don't skip Step 0 — stale `pql.db` makes the rest of the skill lie.
|
||||||
|
- Don't hand-export or hand-stage `.pql/changelog/` — the pre-commit hook does
|
||||||
|
both on every commit. The real footgun is a turn that mutates tickets but
|
||||||
|
never commits: `pql.db` is gitignored and gets rebuilt from the committed
|
||||||
|
changelog on branch switch, silently dropping un-committed mutations. Land
|
||||||
|
at least one commit per ticket-mutating turn (Step 3a).
|
||||||
- Don't activate a batch the user hasn't confirmed.
|
- Don't activate a batch the user hasn't confirmed.
|
||||||
- Don't spawn refinement agents for tickets that have no description — use
|
- Don't spawn refinement agents for tickets that have no description — use
|
||||||
`pql ticket refine` instead; it's cheaper and writes back through the
|
`pql ticket refine` instead; it's cheaper and writes back through the
|
||||||
proper channel.
|
proper channel.
|
||||||
- Don't reach for `gh` — this system doesn't have it. Plain `git` only.
|
|
||||||
- Don't `cd` into subdirectories — run everything from the repo root.
|
- Don't `cd` into subdirectories — run everything from the repo root.
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
# Gitea Actions workflow for clide.
|
|
||||||
#
|
|
||||||
# NOT YET ACTIVATED. Gitea Actions must be enabled in the instance
|
|
||||||
# settings before this runs; until then the file is just a ready-made
|
|
||||||
# pipeline Claude + the user can review.
|
|
||||||
#
|
|
||||||
# When the repo eventually lands on GitHub, copy this file verbatim to
|
|
||||||
# `.github/workflows/test.yml` — Gitea Actions consumes GitHub-Actions
|
|
||||||
# syntax, so no rewrite is needed.
|
|
||||||
|
|
||||||
name: test
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
pull_request:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
unit:
|
|
||||||
name: unit + widget + golden + a11y
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with: { channel: stable, cache: true }
|
|
||||||
- run: dart pub get
|
|
||||||
- run: (cd app && flutter pub get)
|
|
||||||
- run: ci/test.sh
|
|
||||||
- run: ci/test_a11y.sh
|
|
||||||
- run: ci/coverage_gate.sh
|
|
||||||
|
|
||||||
integration:
|
|
||||||
name: integration_test (xvfb)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: unit
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with: { channel: stable, cache: true }
|
|
||||||
- run: sudo apt-get update && sudo apt-get install -y xvfb ninja-build libgtk-3-dev
|
|
||||||
- run: dart pub get
|
|
||||||
- run: (cd app && flutter pub get)
|
|
||||||
- uses: coactions/setup-xvfb@v1
|
|
||||||
with: { run: ci/test_integration.sh }
|
|
||||||
|
|
||||||
startup-bundle:
|
|
||||||
name: bundle smoke (xvfb 5s)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: unit
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with: { channel: stable, cache: true }
|
|
||||||
- run: sudo apt-get update && sudo apt-get install -y xvfb ninja-build libgtk-3-dev
|
|
||||||
- run: dart pub get
|
|
||||||
- run: (cd app && flutter pub get)
|
|
||||||
- run: ci/smoke_bundle.sh
|
|
||||||
|
|
||||||
e2e:
|
|
||||||
name: daemon subprocess + web WASM smoke
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: unit
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with: { channel: stable, cache: true }
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with: { node-version: 20 }
|
|
||||||
- run: dart pub get
|
|
||||||
- run: (cd app && flutter pub get)
|
|
||||||
- run: (cd tools/ui && npm install && npx playwright install --with-deps chromium)
|
|
||||||
- run: ci/test_e2e.sh
|
|
||||||
|
|
||||||
docs:
|
|
||||||
name: dart doc (lib API)
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: subosito/flutter-action@v2
|
|
||||||
with: { channel: stable, cache: true }
|
|
||||||
- run: dart pub get
|
|
||||||
- name: dart doc --validate-links (fail on warning)
|
|
||||||
run: |
|
|
||||||
set -o pipefail
|
|
||||||
dart doc --validate-links 2>&1 | tee dartdoc.log
|
|
||||||
if grep -q "^ warning:" dartdoc.log; then
|
|
||||||
echo "::error::dartdoc emitted warnings — see log above"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: dart-api-docs
|
|
||||||
path: doc/api/
|
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# pql: source .pql/hooks/post-checkout (rebuild pql.db on branch checkout)
|
# pql: source .pql/hooks/post-checkout (rebuild pql.db on branch checkout).
|
||||||
. "$(git rev-parse --show-toplevel)/.pql/hooks/post-checkout"
|
# The pql hook is untracked (a local `pql init` install), so a fresh
|
||||||
|
# `git worktree add` has no .pql/hooks — source it only when present, and
|
||||||
|
# always exit 0: post-checkout is best-effort and must never abort the
|
||||||
|
# checkout / worktree creation.
|
||||||
|
hook="$(git rev-parse --show-toplevel)/.pql/hooks/post-checkout"
|
||||||
|
if [ -f "$hook" ]; then . "$hook"; fi
|
||||||
|
exit 0
|
||||||
|
|||||||
@@ -4,9 +4,62 @@
|
|||||||
# Install: `make hooks` (points git core.hooksPath at .githooks/).
|
# Install: `make hooks` (points git core.hooksPath at .githooks/).
|
||||||
# Bypass: never. If this runs slowly, fix the slow test; don't reach
|
# Bypass: never. If this runs slowly, fix the slow test; don't reach
|
||||||
# for --no-verify (git-commit skill forbids it).
|
# for --no-verify (git-commit skill forbids it).
|
||||||
|
#
|
||||||
|
# Fast path (T-348, widened T-393): run the full ~2min test suite when the push
|
||||||
|
# touches lib/ (app + runtime Dart source), pubspec.* (deps / version), or the
|
||||||
|
# things that can themselves break the suite or this gate — test/, ci/, and
|
||||||
|
# .githooks/. (The old regex matched only lib/ and pubspec.*, so a push that
|
||||||
|
# ONLY changed a test, a ci/ gate script, or this hook skipped the whole suite.)
|
||||||
|
# Pure assets/docs changes still ride along with the next lib-touching push.
|
||||||
|
# There is no release CI — the full suite is only ever run here or via
|
||||||
|
# `make push-check`. So a push touching none of the above runs just the instant
|
||||||
|
# decisions + changelog gates. A state we can't classify (unfetched remote, new
|
||||||
|
# branch) runs the full gate.
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
cd "$(git rev-parse --show-toplevel)"
|
cd "$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
z40=0000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
# Collect every file changed across the commits being pushed. git feeds the
|
||||||
|
# hook one line per ref on stdin: <local-ref> <local-sha> <remote-ref> <remote-sha>.
|
||||||
|
changed=""
|
||||||
|
force_full=0
|
||||||
|
while read -r _local_ref local_sha _remote_ref remote_sha; do
|
||||||
|
[[ "$local_sha" == "$z40" ]] && continue # branch deletion — nothing to test
|
||||||
|
if [[ "$remote_sha" == "$z40" ]]; then
|
||||||
|
# New remote branch: diff from its merge-base with main, else play it safe.
|
||||||
|
base="$(git merge-base "$local_sha" origin/main 2>/dev/null || true)"
|
||||||
|
else
|
||||||
|
base="$remote_sha"
|
||||||
|
fi
|
||||||
|
# If we can't resolve a base locally (e.g. the remote advanced and we haven't
|
||||||
|
# fetched its objects), we can't classify the diff — run the full gate.
|
||||||
|
if [[ -z "$base" ]] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
|
||||||
|
force_full=1
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
changed+=$'\n'"$(git diff --name-only "$base" "$local_sha")"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Paths that force the full gate: source (lib/), deps/version (pubspec.*), and
|
||||||
|
# the dirs that can themselves break the suite or this gate (test/, ci/,
|
||||||
|
# .githooks/). Single source of truth — test/tooling/pre_push_hook_test.dart
|
||||||
|
# reads this exact pattern, so narrowing it fails that test (the T-393 guard).
|
||||||
|
trigger_re='^(lib/|test/|ci/|\.githooks/|pubspec\.)'
|
||||||
|
|
||||||
|
# Run the full gate when a trigger path is touched, or when we couldn't classify
|
||||||
|
# above.
|
||||||
|
needs_gate=1
|
||||||
|
if [[ "$force_full" -eq 0 ]]; then
|
||||||
|
trigger_files="$(printf '%s\n' "$changed" | grep -E "$trigger_re" || true)"
|
||||||
|
[[ -z "$trigger_files" ]] && needs_gate=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$needs_gate" -eq 0 ]]; then
|
||||||
|
echo "==> pre-push: no source/test/ci/hook/pubspec change — decisions + changelog gates, skipping tests"
|
||||||
|
make decisions-validate changelog-gate
|
||||||
|
else
|
||||||
echo "==> pre-push: make push-check"
|
echo "==> pre-push: make push-check"
|
||||||
make push-check
|
make push-check
|
||||||
|
fi
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
# Build + publish versioned Windows and Linux release bundles when the version
|
||||||
|
# in pubspec.yaml changes on main. The `version` job only proceeds when the
|
||||||
|
# v<version> tag doesn't already exist, so an unrelated pubspec edit is a no-op.
|
||||||
|
#
|
||||||
|
# FIRST CUT — neither build has run in CI yet (Windows has never been built at
|
||||||
|
# all), so expect to iterate on these from the first run's logs. The repo's own
|
||||||
|
# `make` targets are the build contract (gen-build-info + clide-cli + flutter
|
||||||
|
# build, all wired in `make build`).
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
paths: ['pubspec.yaml']
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write # create the tag + the release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.v.outputs.version }}
|
||||||
|
fresh: ${{ steps.v.outputs.fresh }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 0 } # tags, to tell new vs. already-released
|
||||||
|
- id: v
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
version=$(awk -F': *' '/^version:/ {gsub(/[" ]/,"",$2); print $2; exit}' pubspec.yaml)
|
||||||
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
if git rev-parse "v$version" >/dev/null 2>&1; then
|
||||||
|
echo "fresh=false" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "v$version already tagged — nothing to release."
|
||||||
|
else
|
||||||
|
echo "fresh=true" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "v$version is new — building."
|
||||||
|
fi
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
needs: version
|
||||||
|
if: needs.version.outputs.fresh == 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable }
|
||||||
|
- run: sudo apt-get update && sudo apt-get install -y ninja-build libgtk-3-dev
|
||||||
|
- run: make dugite-fetch
|
||||||
|
- run: make build # gen-build-info + clide-cli + flutter build linux
|
||||||
|
- name: package
|
||||||
|
run: tar -C build/linux/x64/release/bundle -czf clide-linux-x64-${{ needs.version.outputs.version }}.tar.gz .
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with: { name: linux, path: clide-linux-x64-*.tar.gz }
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
needs: version
|
||||||
|
if: needs.version.outputs.fresh == 'true'
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable }
|
||||||
|
- run: choco install -y make
|
||||||
|
- name: build
|
||||||
|
shell: bash
|
||||||
|
run: make dugite-fetch && make build # MSVC + bash already on windows-latest
|
||||||
|
- name: package
|
||||||
|
shell: pwsh
|
||||||
|
run: Compress-Archive -Path build/windows/x64/runner/Release/* -DestinationPath clide-windows-x64-${{ needs.version.outputs.version }}.zip
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with: { name: windows, path: clide-windows-x64-*.zip }
|
||||||
|
|
||||||
|
publish:
|
||||||
|
needs: [version, build-linux, build-windows]
|
||||||
|
if: needs.version.outputs.fresh == 'true'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: changelog notes for this version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
ver="${{ needs.version.outputs.version }}"
|
||||||
|
# Pull the entries under `## [<version>]` — the changelog cut that the
|
||||||
|
# version-bump commit lands per the changelog discipline — as the
|
||||||
|
# release body; fall back to a one-liner if the section is absent.
|
||||||
|
awk -v ver="$ver" '
|
||||||
|
$0 ~ "^## \\[" ver "\\]" {grab=1; next}
|
||||||
|
grab && /^## \[/ {exit}
|
||||||
|
grab {print}
|
||||||
|
' CHANGELOG.md > release-notes.md
|
||||||
|
[ -s release-notes.md ] || echo "Release v$ver." > release-notes.md
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with: { path: dist }
|
||||||
|
- uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
tag_name: v${{ needs.version.outputs.version }}
|
||||||
|
name: clide v${{ needs.version.outputs.version }}
|
||||||
|
body_path: release-notes.md # the version's CHANGELOG section
|
||||||
|
generate_release_notes: true # + auto commit list appended
|
||||||
|
files: dist/**/* # the built versioned bundles
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
name: test
|
||||||
|
|
||||||
|
# Linux CI for clide (GitHub Actions). Moved here from .gitea/workflows/ when CI
|
||||||
|
# consolidated onto GitHub (the primary remote); the Gitea secondary has Actions
|
||||||
|
# disabled. Pairs with windows.yml (ConPTY suite on windows-latest) and
|
||||||
|
# release.yml (versioned release bundles).
|
||||||
|
#
|
||||||
|
# Steps go through the make targets (the repo's tooling-discipline rule: the
|
||||||
|
# make layer sets up the environment — gen-build-info etc. — and stays correct
|
||||||
|
# if a wrapped script moves).
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
unit:
|
||||||
|
name: unit + widget + golden + a11y + coverage gate
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable, cache: true }
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: install pql
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
gh release download --repo postmeridiem/pql --pattern 'pql_*_Linux_x86_64.tar.gz' --output /tmp/pql.tgz
|
||||||
|
tar -xzf /tmp/pql.tgz -C /tmp
|
||||||
|
sudo install -m 0755 /tmp/pql /usr/local/bin/pql
|
||||||
|
pql --version
|
||||||
|
# The pql tests query the repo's vault, but .pql/pql.db is gitignored
|
||||||
|
# (the post-checkout hook rebuilds it from the committed changelog).
|
||||||
|
# A fresh CI checkout has the changelog but no db — materialize it,
|
||||||
|
# and sync decision records from the governance/ DQR markdown tree
|
||||||
|
# (tickets come from the changelog; decisions from `decisions sync`).
|
||||||
|
pql plan import
|
||||||
|
pql decisions sync
|
||||||
|
# test-coverage runs the full fast suite WITH coverage (it includes the
|
||||||
|
# a11y suite — see the push-check note in the Makefile), which is what
|
||||||
|
# coverage-gate consumes.
|
||||||
|
- run: make test-coverage
|
||||||
|
- run: make coverage-gate
|
||||||
|
|
||||||
|
integration:
|
||||||
|
name: integration_test (xvfb)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: unit
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable, cache: true }
|
||||||
|
- run: sudo apt-get update && sudo apt-get install -y xvfb ninja-build libgtk-3-dev
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: install pql
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
gh release download --repo postmeridiem/pql --pattern 'pql_*_Linux_x86_64.tar.gz' --output /tmp/pql.tgz
|
||||||
|
tar -xzf /tmp/pql.tgz -C /tmp
|
||||||
|
sudo install -m 0755 /tmp/pql /usr/local/bin/pql
|
||||||
|
pql --version
|
||||||
|
# The pql tests query the repo's vault, but .pql/pql.db is gitignored
|
||||||
|
# (the post-checkout hook rebuilds it from the committed changelog).
|
||||||
|
# A fresh CI checkout has the changelog but no db — materialize it,
|
||||||
|
# and sync decision records from the governance/ DQR markdown tree
|
||||||
|
# (tickets come from the changelog; decisions from `decisions sync`).
|
||||||
|
pql plan import
|
||||||
|
pql decisions sync
|
||||||
|
- uses: coactions/setup-xvfb@v1
|
||||||
|
with: { run: make test-integration }
|
||||||
|
|
||||||
|
startup-bundle:
|
||||||
|
name: bundle smoke (xvfb 5s)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: unit
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable, cache: true }
|
||||||
|
- run: sudo apt-get update && sudo apt-get install -y xvfb ninja-build libgtk-3-dev
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: install pql
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
run: |
|
||||||
|
gh release download --repo postmeridiem/pql --pattern 'pql_*_Linux_x86_64.tar.gz' --output /tmp/pql.tgz
|
||||||
|
tar -xzf /tmp/pql.tgz -C /tmp
|
||||||
|
sudo install -m 0755 /tmp/pql /usr/local/bin/pql
|
||||||
|
pql --version
|
||||||
|
# The pql tests query the repo's vault, but .pql/pql.db is gitignored
|
||||||
|
# (the post-checkout hook rebuilds it from the committed changelog).
|
||||||
|
# A fresh CI checkout has the changelog but no db — materialize it,
|
||||||
|
# and sync decision records from the governance/ DQR markdown tree
|
||||||
|
# (tickets come from the changelog; decisions from `decisions sync`).
|
||||||
|
pql plan import
|
||||||
|
pql decisions sync
|
||||||
|
# Point the real release app's crash logs at an uploadable workspace dir
|
||||||
|
# (T-436): if the bundle wedges on boot, the watchdog heartbeat/sample +
|
||||||
|
# FileLogSink land here and get uploaded below. CLIDE_LOG=debug so the
|
||||||
|
# file sink captures info/debug, not just the release-default warn.
|
||||||
|
- name: bundle smoke (logs → artifact)
|
||||||
|
env:
|
||||||
|
CLIDE_LOG: debug
|
||||||
|
CLIDE_LOG_DIR: ${{ github.workspace }}/clide-logs
|
||||||
|
run: make smoke-bundle
|
||||||
|
- name: Upload crash logs
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: bundle-crash-logs
|
||||||
|
path: ${{ github.workspace }}/clide-logs
|
||||||
|
if-no-files-found: ignore
|
||||||
|
|
||||||
|
web-wasm:
|
||||||
|
name: web build (wasm compile gate)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable, cache: true }
|
||||||
|
- run: flutter pub get
|
||||||
|
# Compile gate for the dart:ffi web fence (D-100 / T-438, resolving Q-50):
|
||||||
|
# every native binding lives behind a `dart.library.ffi` conditional import
|
||||||
|
# with a web stub. If a new one lands without its stub, this fails — the
|
||||||
|
# fence can't silently rot. Build-only for now; the full web-WASM Playwright
|
||||||
|
# e2e (`make test-e2e`: setup-node + playwright install in tools/ui +
|
||||||
|
# serve) is the follow-on once the harness is wired back up.
|
||||||
|
- run: flutter build web --wasm
|
||||||
|
|
||||||
|
docs:
|
||||||
|
name: dart doc (lib API)
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with: { channel: stable, cache: true }
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: dart doc --validate-links (fail on warning)
|
||||||
|
run: |
|
||||||
|
set -o pipefail
|
||||||
|
dart doc --validate-links 2>&1 | tee dartdoc.log
|
||||||
|
if grep -q "^ warning:" dartdoc.log; then
|
||||||
|
echo "::error::dartdoc emitted warnings — see log above"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dart-api-docs
|
||||||
|
path: doc/api/
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
name: windows-soak
|
||||||
|
|
||||||
|
# ConPTY orphan-leak soak on a GitHub-hosted Windows runner — the cheap
|
||||||
|
# alternative to a dedicated Windows VM. The freeze hypothesis (T-424) is that
|
||||||
|
# each WindowsPty.start() leaks its conhost/OpenConsole host because the child
|
||||||
|
# is not in a kill-on-close Job Object; across many runs those hosts pile up
|
||||||
|
# until the box starves. tools/windows-verify/soak-conpty.ps1 reproduces that
|
||||||
|
# WITHOUT crashing: it runs the ConPTY suite many times IN ONE job and counts
|
||||||
|
# the hosts that survive each dart.exe exit. A throwaway runner is fine — we
|
||||||
|
# watch the accumulation (the leading indicator), not the reboot. The repeated
|
||||||
|
# runs happen inside this single job, so the leak can build up here even though
|
||||||
|
# the runner is discarded afterwards (cf. the note in windows.yml, which only
|
||||||
|
# runs the suite once).
|
||||||
|
#
|
||||||
|
# Diagnostic, never a gate: it always exits 0 and just publishes the verdict +
|
||||||
|
# CSV. Runs on demand (workflow_dispatch) and when the soak kit itself changes.
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
iterations:
|
||||||
|
description: How many times to run the ConPTY suite (clean-path soak)
|
||||||
|
default: "25"
|
||||||
|
kill_iterations:
|
||||||
|
description: Spawn+force-kill cycles (abrupt-death orphan probe)
|
||||||
|
default: "15"
|
||||||
|
ptys_per_iter:
|
||||||
|
description: WindowsPty sessions spawned per kill cycle
|
||||||
|
default: "2"
|
||||||
|
push:
|
||||||
|
branches: [windows-support]
|
||||||
|
paths:
|
||||||
|
- tools/windows-verify/**
|
||||||
|
- .github/workflows/windows-soak.yml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
conpty-soak:
|
||||||
|
runs-on: windows-latest
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
- run: flutter --version
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: ConPTY orphan-leak soak
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$iters = "${{ github.event.inputs.iterations }}"
|
||||||
|
if (-not $iters) { $iters = "25" }
|
||||||
|
tools/windows-verify/soak-conpty.ps1 -Iterations ([int]$iters) -OutDir "$env:GITHUB_WORKSPACE/soak-out"
|
||||||
|
- name: Publish verdict to job summary
|
||||||
|
if: always()
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$s = Get-ChildItem "$env:GITHUB_WORKSPACE/soak-out/*.summary.txt" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||||
|
if ($s) { Get-Content $s.FullName | Add-Content $env:GITHUB_STEP_SUMMARY }
|
||||||
|
- name: Upload soak CSV + summary
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: conpty-soak
|
||||||
|
path: soak-out
|
||||||
|
if-no-files-found: warn
|
||||||
|
|
||||||
|
conpty-kill-probe:
|
||||||
|
# Abrupt-death half: force-kill the parent dart.exe mid-life (no close(),
|
||||||
|
# no Job Object) and count the ConPTY hosts that survive. This is the path
|
||||||
|
# the freeze hypothesis (T-424) actually implicates — the clean-path soak
|
||||||
|
# above never exercises it. Diagnostic only; always succeeds.
|
||||||
|
runs-on: windows-latest
|
||||||
|
timeout-minutes: 30
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
- run: flutter --version
|
||||||
|
- run: flutter pub get
|
||||||
|
- name: ConPTY abrupt-death orphan probe
|
||||||
|
shell: pwsh
|
||||||
|
# CLIDE_LOG_DIR makes the probe emit FFI breadcrumbs (T-436): when a
|
||||||
|
# parent is force-killed mid-life, its reader/waiter isolates' last
|
||||||
|
# crumb ("ReadFile enter" / "WaitForSingleObject enter") is fsynced to
|
||||||
|
# clide-pty.crumbs.log and uploaded below — naming what the wedged
|
||||||
|
# isolate was doing at the instant of death.
|
||||||
|
env:
|
||||||
|
CLIDE_LOG_DIR: ${{ github.workspace }}/kill-crumbs
|
||||||
|
run: |
|
||||||
|
$iters = "${{ github.event.inputs.kill_iterations }}"
|
||||||
|
if (-not $iters) { $iters = "15" }
|
||||||
|
$ptys = "${{ github.event.inputs.ptys_per_iter }}"
|
||||||
|
if (-not $ptys) { $ptys = "2" }
|
||||||
|
tools/windows-verify/soak-conpty-kill.ps1 -Iterations ([int]$iters) -PtysPerIter ([int]$ptys) -OutDir "$env:GITHUB_WORKSPACE/kill-out"
|
||||||
|
- name: Publish verdict to job summary
|
||||||
|
if: always()
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$s = Get-ChildItem "$env:GITHUB_WORKSPACE/kill-out/*.summary.txt" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||||
|
if ($s) { Get-Content $s.FullName | Add-Content $env:GITHUB_STEP_SUMMARY }
|
||||||
|
- name: Upload kill-probe CSV + summary
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: conpty-kill-probe
|
||||||
|
path: kill-out
|
||||||
|
if-no-files-found: warn
|
||||||
|
- name: Upload FFI breadcrumbs (last act of each killed reader/waiter)
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: conpty-kill-crumbs
|
||||||
|
path: ${{ github.workspace }}/kill-crumbs
|
||||||
|
if-no-files-found: ignore
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
name: windows
|
||||||
|
|
||||||
|
# Windows CI on GitHub-hosted runners — the only hosted Windows available, and
|
||||||
|
# GitHub is clide's primary remote (the Gitea secondary is self-hosted Linux and
|
||||||
|
# keeps running the Linux suite). This is the first real execution of the ConPTY
|
||||||
|
# backend (lib/src/pty/windows_pty.dart), so expect genuine failures until the
|
||||||
|
# Windows fixes land (T-424). Keep this OUT of required status checks until it's
|
||||||
|
# reliably green — it reports + uploads artifacts without blocking merges. Each
|
||||||
|
# run is a fresh, discarded runner, so the accumulation freeze (which needs
|
||||||
|
# repeated runs on one machine) can't build up here.
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, windows-support]
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
windows-pty:
|
||||||
|
runs-on: windows-latest
|
||||||
|
timeout-minutes: 25
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: subosito/flutter-action@v2
|
||||||
|
with:
|
||||||
|
channel: stable
|
||||||
|
- run: flutter --version
|
||||||
|
- run: flutter pub get
|
||||||
|
# No `flutter analyze` here: it's platform-agnostic — the Linux job already
|
||||||
|
# analyzes windows_pty.dart and everything else statically, and the
|
||||||
|
# `flutter build windows` release job catches Windows-specific compile
|
||||||
|
# errors. Skipping it also avoids needing `make gen-build-info`, since the
|
||||||
|
# pty tests import the pty libraries directly, not the build_info-bearing
|
||||||
|
# barrel (lib/clide.dart). This job's unique value is running real ConPTY.
|
||||||
|
- name: ConPTY + Windows-arg unit tests
|
||||||
|
# windows_pty_test.dart drives real ConPTY (it self-skips off-Windows);
|
||||||
|
# the args/size suites are the pure-logic coverage. --timeout 60s so a
|
||||||
|
# wedged reader fails fast instead of hanging the runner.
|
||||||
|
run: dart test --concurrency=1 --timeout 60s test/pty/windows_pty_test.dart test/pty/windows_pty_args_test.dart test/pty/pty_size_test.dart
|
||||||
|
- name: Upload test output / logs
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: windows-test-output
|
||||||
|
# T-425 (crash-survivable FileLogSink) writes under %LOCALAPPDATA%\clide\logs;
|
||||||
|
# add that path here once it lands so a freeze leaves a downloadable log.
|
||||||
|
path: test/.test-output
|
||||||
|
if-no-files-found: ignore
|
||||||
+35
@@ -1,6 +1,12 @@
|
|||||||
# -- macOS sandbox (machine-specific paths; template is committed) ------
|
# -- macOS sandbox (machine-specific paths; template is committed) ------
|
||||||
/macos/Runner/DebugProfile.entitlements
|
/macos/Runner/DebugProfile.entitlements
|
||||||
|
|
||||||
|
# -- clean-house skill run history / skip ledger (machine-local) --------
|
||||||
|
/governance/decisions/.clean-house-state.md
|
||||||
|
|
||||||
|
# -- frame0 wireframe local↔Frame0 id mapping (machine-local) -----------
|
||||||
|
**/*.idmap.json
|
||||||
|
|
||||||
# -- Flutter / Dart (single package at repo root) -----------------------
|
# -- Flutter / Dart (single package at repo root) -----------------------
|
||||||
/.dart_tool/
|
/.dart_tool/
|
||||||
/.packages
|
/.packages
|
||||||
@@ -37,6 +43,24 @@ tools/ui/.serve.pid
|
|||||||
# coverage/ is committed.
|
# coverage/ is committed.
|
||||||
/coverage/
|
/coverage/
|
||||||
|
|
||||||
|
# -- Tee'd flutter-test output (see Makefile `make t T=...`) ---------
|
||||||
|
# Lives under test/ so the repo root stays uncluttered.
|
||||||
|
/test/.test-output/
|
||||||
|
|
||||||
|
# -- Build-time stamps generated by `make gen-build-info` -----------
|
||||||
|
# version (from pubspec.yaml), commit (git short SHA), date (UTC).
|
||||||
|
# Regenerated on every make build/run/test target.
|
||||||
|
/lib/src/build_info.g.dart
|
||||||
|
|
||||||
|
# -- Built C `clide` shell client (T-126). Source under ----------
|
||||||
|
# native/clide-cli/ stays in git; the per-platform compiled binary
|
||||||
|
# is built by `make clide-cli`.
|
||||||
|
/native/linux-x64/clide
|
||||||
|
/native/macos-arm64/clide
|
||||||
|
/native/macos-x64/clide
|
||||||
|
/native/windows-x64/clide.exe
|
||||||
|
/native/windows-x64/clide.obj
|
||||||
|
|
||||||
# -- Test, coverage, profile output ------------------------------------
|
# -- Test, coverage, profile output ------------------------------------
|
||||||
*.test
|
*.test
|
||||||
*.out
|
*.out
|
||||||
@@ -104,3 +128,14 @@ legacy/**/.coverage.*
|
|||||||
*.idmap.json
|
*.idmap.json
|
||||||
.pql/*
|
.pql/*
|
||||||
!.pql/changelog/
|
!.pql/changelog/
|
||||||
|
!.pql/pql-plan.json
|
||||||
|
|
||||||
|
# -- Local build / env artefacts (root-anchored; never tracked) ---------
|
||||||
|
/.coverage
|
||||||
|
/.venv/
|
||||||
|
/dist/
|
||||||
|
/logs/
|
||||||
|
/firebase-debug.log
|
||||||
|
# stray Python trees at the root (the real Dart suite is test/, singular)
|
||||||
|
/clide/
|
||||||
|
/tests/
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "cc0734ac716fbb8b90f3f9db8020958b1553afa7"
|
revision: "c9a6c484230f8b5e408ec57be1ef71dee1e77020"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
@@ -13,11 +13,11 @@ project_type: app
|
|||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7
|
create_revision: c9a6c484230f8b5e408ec57be1ef71dee1e77020
|
||||||
base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7
|
base_revision: c9a6c484230f8b5e408ec57be1ef71dee1e77020
|
||||||
- platform: web
|
- platform: windows
|
||||||
create_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7
|
create_revision: c9a6c484230f8b5e408ec57be1ef71dee1e77020
|
||||||
base_revision: cc0734ac716fbb8b90f3f9db8020958b1553afa7
|
base_revision: c9a6c484230f8b5e408ec57be1ef71dee1e77020
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- Changelog format marker, written by pql. Comments only: this file
|
||||||
|
-- is never executed — Import descends into the per-table directories
|
||||||
|
-- and does not read the changelog root.
|
||||||
|
--
|
||||||
|
-- A changelog carrying no marker is format 1, the shape that existed
|
||||||
|
-- before formats were versioned. An older format is migrated forward
|
||||||
|
-- by `pql plan upgrade` (and automatically from the post-merge hook);
|
||||||
|
-- a newer one is refused rather than replayed under rules this binary
|
||||||
|
-- does not know. See D-28 and docs/versions.md.
|
||||||
|
-- pql:changelog_format: 2.0.0
|
||||||
|
-- pql:written_by: 2.0.0
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
-- Auto-generated by pql init. CREATE TABLE statements
|
-- Auto-generated by migrate-ids (D-26). CREATE TABLE statements
|
||||||
-- for the planning schema; per-table dir keeps the changelog
|
-- for the planning schema; per-table dir keeps the changelog
|
||||||
-- self-describing per D-15. CREATE TABLE IF NOT EXISTS is
|
-- self-describing per D-15.
|
||||||
-- idempotent so running schema files from each directory in
|
-- pql:created_by: migrate-ids
|
||||||
-- replay order is harmless.
|
-- pql:canonical_version: 2
|
||||||
--
|
|
||||||
-- Importer parses the markers below to detect schema drift
|
|
||||||
-- between the producing pql version and the local one — a
|
|
||||||
-- bumped canonical_version means projection rules changed
|
|
||||||
-- and replay must refuse rather than silently corrupt state.
|
|
||||||
-- pql:created_by: 1.4.26
|
|
||||||
-- pql:canonical_version: 1
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS decisions (
|
CREATE TABLE IF NOT EXISTS decisions (
|
||||||
@@ -43,14 +36,23 @@ CREATE TABLE IF NOT EXISTS decision_refs (
|
|||||||
PRIMARY KEY (source_id, target_id, ref_type)
|
PRIMARY KEY (source_id, target_id, ref_type)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Identity split (D-26): a ticket's stable, collision-proof identity is its
|
||||||
|
-- record_id (a locally-generated ULID, planning.NewRecordID); the friendly
|
||||||
|
-- T-NNN label lives in ticket_idmap and may be reconciled. Every structural
|
||||||
|
-- reference (parent, deps, history, labels) targets record_id, so a label
|
||||||
|
-- clash never corrupts the graph — only ticket_idmap needs a relabel.
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
id TEXT PRIMARY KEY,
|
record_id TEXT PRIMARY KEY,
|
||||||
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
||||||
parent_id TEXT REFERENCES tickets(id),
|
parent_record_id TEXT REFERENCES tickets(record_id),
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'backlog'
|
-- No CHECK enumeration: the ticket status vocabulary is per-vault
|
||||||
CHECK(status IN ('backlog','ready','in_progress','review','done','cancelled')),
|
-- configurable (ticket_statuses in .pql/config.yaml). Validation lives
|
||||||
|
-- in Go (planning.StatusSet), so adding/renaming statuses needs no
|
||||||
|
-- schema change. The DEFAULT is a harmless fallback — CreateTicket
|
||||||
|
-- always inserts the configured default explicitly.
|
||||||
|
status TEXT NOT NULL DEFAULT 'backlog',
|
||||||
priority TEXT DEFAULT 'medium'
|
priority TEXT DEFAULT 'medium'
|
||||||
CHECK(priority IN ('critical','high','medium','low')),
|
CHECK(priority IN ('critical','high','medium','low')),
|
||||||
assigned_to TEXT,
|
assigned_to TEXT,
|
||||||
@@ -63,19 +65,33 @@ CREATE TABLE IF NOT EXISTS tickets (
|
|||||||
canonical_version INTEGER
|
canonical_version INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- ticket_idmap maps a record_id to its current friendly label (T-NNN).
|
||||||
|
-- ticket_id is intentionally NOT globally unique: two uncoordinated clones
|
||||||
|
-- can mint the same label, which surfaces as a duplicate-label collision
|
||||||
|
-- (detected at replay) and is fixed with "pql ticket relabel".
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_idmap (
|
||||||
|
record_id TEXT PRIMARY KEY REFERENCES tickets(record_id),
|
||||||
|
ticket_id TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_deps (
|
CREATE TABLE IF NOT EXISTS ticket_deps (
|
||||||
blocker_id TEXT NOT NULL REFERENCES tickets(id),
|
blocker_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
blocked_id TEXT NOT NULL REFERENCES tickets(id),
|
blocked_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (blocker_id, blocked_id)
|
PRIMARY KEY (blocker_record_id, blocked_record_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_history (
|
CREATE TABLE IF NOT EXISTS ticket_history (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
field TEXT NOT NULL,
|
field TEXT NOT NULL,
|
||||||
old_value TEXT,
|
old_value TEXT,
|
||||||
new_value TEXT,
|
new_value TEXT,
|
||||||
@@ -89,14 +105,14 @@ CREATE TABLE IF NOT EXISTS ticket_history (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_labels (
|
CREATE TABLE IF NOT EXISTS ticket_labels (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
label TEXT NOT NULL,
|
label TEXT NOT NULL,
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (ticket_id, label)
|
PRIMARY KEY (ticket_record_id, label)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS meta (
|
CREATE TABLE IF NOT EXISTS meta (
|
||||||
@@ -109,6 +125,8 @@ CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
|||||||
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_record_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ticket_idmap_label ON ticket_idmap(ticket_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM6KY9JVRKF22GGFMXR', '2026-05-18 11:59:28', '2026-05-18 11:59:28', NULL, 'ade2722e88d76b4ea6264545ff9b5398', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM78E2NAM4YK3A2AV6R', '2026-05-18 11:59:31', '2026-05-18 11:59:31', NULL, 'd996c0868b309fd7719ab4a8c2e0dd2b', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KY9JVRKF22GGFMXR', '06FB0TNQM78E2NAM4YK3A2AV6R', '2026-05-18 11:59:34', '2026-05-18 11:59:34', NULL, '05db5396eae627dbfae19415bf12802b', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM7J40S0A8Q8PC0PDY8', '2026-05-18 11:59:37', '2026-05-18 11:59:37', NULL, '44a606dc211dc172a0b7e45dca353555', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7J40S0A8Q8PC0PDY8', '06FB0TNQM6KEY6593FMW8Y40VC', '2026-05-18 11:59:41', '2026-05-18 11:59:41', NULL, 'a5958fcc4bc52bcba6c5d22119c1152a', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM40XWGSN99DBDQDHJR', '2026-05-18 11:59:44', '2026-05-18 11:59:44', NULL, 'fd9d60cea050f1b2a8657664150e977c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78E2NAM4YK3A2AV6R', '06FB0TNQM40XWGSN99DBDQDHJR', '2026-05-18 11:59:47', '2026-05-18 11:59:47', NULL, '32e0aec7ec29068519dbd31c8a8cdc80', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM5MW2V3QCMWKMY4VQM', '2026-05-18 11:59:51', '2026-05-18 11:59:51', NULL, 'cd33e0846477b82b5cf7e00781783b8c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78E2NAM4YK3A2AV6R', '06FB0TNQM5ZSRZARG7SXCC71NM', '2026-05-18 11:59:54', '2026-05-18 11:59:54', NULL, '4ce716dceb22197381bbf6f7f5cb339c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KEY6593FMW8Y40VC', '06FB0TNQM5ZSRZARG7SXCC71NM', '2026-05-18 11:59:54', '2026-05-18 11:59:54', NULL, '51d502ceb0a41091beb46513618b5b04', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KY9JVRKF22GGFMXR', '06FB0TNQM5ZSRZARG7SXCC71NM', '2026-05-18 11:59:54', '2026-05-18 11:59:54', NULL, '7f4410ea5c072aaac3317a9ed4a99912', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7J40S0A8Q8PC0PDY8', '06FB0TNQM5ZSRZARG7SXCC71NM', '2026-05-18 11:59:54', '2026-05-18 11:59:54', NULL, 'ccd6da9f9358922bc665133b792c65ed', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', '06FB0TNQM5ZSRZARG7SXCC71NM', '2026-05-18 11:59:54', '2026-05-18 11:59:54', NULL, 'd89ba28926b6472133096d779a20f079', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6SRMD12DMXCX6N7DM', '06FB0TNQM6E3X5WWRS09GCDGK8', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '129c875883b4e5a53cdc0683045ace03', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54N0ZDJRS7G6MP1XC', '06FB0TNQM6E3X5WWRS09GCDGK8', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '1b4d4dcf6933819d32df98dff4f89d83', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM653J6604KYDK6RT8R', '06FB0TNQM5AVSMKD15KBJYX48W', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '1c81cdedd045c46a2f1264bcd1067d11', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6E3X5WWRS09GCDGK8', '06FB0TNQM4V1PZ0EK6G60699EM', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '23b6fb946d9de5e730bd186a9ed350e0', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6E3X5WWRS09GCDGK8', '06FB0TNQM5AVSMKD15KBJYX48W', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '876ead25db98c91cadc5ea7caa65b513', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4EQAERS4J9X9RAETR', '06FB0TNQM4V1PZ0EK6G60699EM', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, '91e9aa2d0ffd1f32a52bb5cdf019f3fc', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM653J6604KYDK6RT8R', '06FB0TNQM5V9RNW2BGT5GHRTRG', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, 'a8c93af5185bec5604246916460fea08', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4EQAERS4J9X9RAETR', '06FB0TNQM653J6604KYDK6RT8R', '2026-05-22 15:59:56', '2026-05-22 15:59:56', NULL, 'f05aa1ae12d538345bc451d332395b9c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5KN50C7A723SEKZXG', '06FB0TNQM5V9RNW2BGT5GHRTRG', '2026-05-23 06:08:24', '2026-05-23 06:08:24', NULL, 'a0eacf85ca484d159a3dcc6c170f1760', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM77GWREHKA9K45P020', '06FB0TNQM6YSQYCE096R2SFRXG', '2026-05-23 09:52:40', '2026-05-23 09:52:40', NULL, 'bc99438a38a478190cae7e43c4342526', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM77GWREHKA9K45P020', '06FB0TNQM7BJS5E1JJGSJ9XHG0', '2026-05-23 09:52:43', '2026-05-23 09:52:43', NULL, '2a604702bb0023631d5a98810f695439', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM77GWREHKA9K45P020', '06FB0TNQM4XM8EY708NAM1JK00', '2026-05-23 09:52:45', '2026-05-23 09:52:45', NULL, '4303c0c52bfcc9f3dbd48f784ef1adf8', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AHSN3BXZFFWS0EPM', '06FB0TNQM78W48QX3JZP0QYAVW', '2026-05-24 16:27:29', '2026-05-24 16:27:29', NULL, '01db76f1732be386944e3da80fcdc0b4', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AHSN3BXZFFWS0EPM', '06FB0TNQM7G7MK8MP3BGQC36HG', '2026-05-24 16:27:29', '2026-05-24 16:27:29', NULL, 'c71b201e5cbe1f75ccda37657808e448', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AHSN3BXZFFWS0EPM', '06FB0TNQM7KA37YDBJ89GJ27H4', '2026-05-24 16:27:29', '2026-05-24 16:27:29', NULL, 'c9369a0c50aa82e2afa9a7fa70534b61', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AHSN3BXZFFWS0EPM', '06FB0TNQM48P8T23ZPR0BRK6PR', '2026-05-24 16:27:37', '2026-05-24 16:27:37', NULL, '7f6b0dddd7ba67b4db049f3d69b7c807', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48P8T23ZPR0BRK6PR', '06FB0TNQM654XV2TG4K0RVV1CW', '2026-05-24 16:27:43', '2026-05-24 16:27:43', NULL, 'ad5cfd3ff355cd44017ea0898ea14780', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48P8T23ZPR0BRK6PR', '06FB0TNQM6FMAHXM1XAHHCQC60', '2026-05-24 16:27:46', '2026-05-24 16:27:46', NULL, '7365404994faf148b33ab5ddc83fa01d', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM654XV2TG4K0RVV1CW', '06FB0TNQM6FMAHXM1XAHHCQC60', '2026-05-24 16:27:52', '2026-05-24 16:27:52', NULL, 'e3930f2673b82e4e6e0938450c522946', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48P8T23ZPR0BRK6PR', '06FB0TNQM71N3YMS82BAYD3M9R', '2026-05-24 16:27:56', '2026-05-24 16:27:56', NULL, '856fdd59d24643888245f06c621f40b8', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM654XV2TG4K0RVV1CW', '06FB0TNQM6V6TKRPA106D5SMMM', '2026-05-25 09:16:24', '2026-05-25 09:16:24', NULL, '329210f950241271814a8ed1255aa993', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48P8T23ZPR0BRK6PR', '06FB0TNQM67ET3VQP90WRXVSMG', '2026-05-25 09:16:24', '2026-05-25 09:16:24', NULL, '8a8027ce60a1ec2566c0b32f67f7759b', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4W624VD4JW1GHDHAR', '06FB0TNQM7WE0SD9N4HCP9BB64', '2026-05-25 09:26:48', '2026-05-25 09:26:48', NULL, '388878e0c968776f9bc7a61934dbd3d6', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6YYG4X5R1GX97TJB4', '06FB0TNQM452XPSG99PA60ZZ48', '2026-05-31 18:01:19', '2026-05-31 18:01:19', NULL, '06723eeaf4ac4b3ca32e24df249de904', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM65R8CNFNE1MA5GGR0', '06FB0TNQM4PH1J6ENYT4PJZRHG', '2026-06-01 18:48:57', '2026-06-01 18:48:57', NULL, '1faf4292ceab6cfe3550dfedad554efe', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4PH1J6ENYT4PJZRHG', '06FB0TNQM5REFZXMY8ESWN0Z90', '2026-06-01 18:48:57', '2026-06-01 18:48:57', NULL, 'ca9731f8247e19ee44e99f51b4c33ba2', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M83TTXHRXESFZY14', '06FB0TNQM5REFZXMY8ESWN0Z90', '2026-06-01 18:48:58', '2026-06-01 18:48:58', NULL, '097bef3723659e681584982688cb242f', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54WTNQDMYT0AVR4WM', '06FB0TNQM78J2H2S0R79SSSPW8', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '112f7b091860de0dc7246f2c1b0eea45', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6Y5SET5WGSS2W78F8', '06FB0TNQM758PXMJH16PA3JHFW', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '497eb0cb7db0b11194031874d6e8d89d', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7171NRB1T82TGP5RG', '06FB0TNQM78J2H2S0R79SSSPW8', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '5102b2f239c5c18631997cbc1f2d998c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6EGSD0SB7NYNSP1BM', '06FB0TNQM758PXMJH16PA3JHFW', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, '9d0c7bbff8117a3569cf3b7937228184', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4C2PSN2GVJY9JDSZG', '06FB0TNQM7171NRB1T82TGP5RG', '2026-06-02 18:13:52', '2026-06-02 18:13:52', NULL, 'd935e3d2978a3584efb0767e75737e84', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM45HHRBCRMV2166Y6M', '06FB0TNQM5YYMMKFD5Z8WG9F60', '2026-06-07 08:49:16', '2026-06-07 08:49:16', NULL, '11d94aab7a635da1ffb610aa2ade2061', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM551VZ2NYV6PD0XQRC', '06FB0TNQM4XBRZJ6DEHFWREWC0', '2026-06-07 10:42:46', '2026-06-07 10:42:46', NULL, 'daa1e2dd097721230deca67500c1c00d', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM551VZ2NYV6PD0XQRC', '06FB0TNQM67PDXAFTPPW7B1WDR', '2026-06-07 10:42:50', '2026-06-07 10:42:50', NULL, '50bb0fcfafb5aacdd747bd9fcd6a3ea6', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB234WP4Y6Q16A0HFW8BSXMG', '2026-06-10 11:12:11', '2026-06-10 11:12:11', NULL, 'e0876fe73623c4063849a13f99d552f5', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB234WP4Y6Q16A0HFW8BSXMG', '2026-06-10 11:12:11', '2026-06-10 11:12:14', NULL, 'cd39602b20a0681e3cca2dfee38d1734', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2ESCR4V6V07CRH18FBCDN8', '2026-06-10 11:12:18', '2026-06-10 11:12:18', NULL, 'c74a2c5d562157c24c11c8fa5d04799e', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2ETJQP0CT6X7W3CWZ6NS9G', '2026-06-10 11:12:20', '2026-06-10 11:12:20', NULL, 'cb20764a77d2a15290ed61a186542095', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2EV29HSK6EJ5VF50R87VC4', '2026-06-10 11:12:25', '2026-06-10 11:12:25', NULL, 'dd9434426790edcaa556221f74c431ba', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2G1WD1839Z90AQ5C0BHNV4', '2026-06-10 11:17:25', '2026-06-10 11:17:25', NULL, '5535e3d16bee2a2cdfcbeb84ea3fca99', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5TWC00GW0P3X02HZW', '06FB2TY91VHK7TPKPMZ11EG3TM', '2026-06-10 12:04:53', '2026-06-10 12:04:53', NULL, 'ed3717d8f6467c0a77236eda670efce5', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5TWC00GW0P3X02HZW', '06FB2TY91VHK7TPKPMZ11EG3TM', '2026-06-10 12:04:53', '2026-06-10 12:05:01', '2026-06-10 12:05:01', '137cd047c9eaec01cac955b49fedd839', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DJZDDZ00BSA04B660RS7M', '06FB3DKQQJ583944DG8561VQ3G', '2026-06-10 13:27:04', '2026-06-10 13:27:04', NULL, '73383d1011fbad641395f27271b141e6', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DKQQJ583944DG8561VQ3G', '06FB3DMF20SYFDT6WX2RFBQXKW', '2026-06-10 13:27:04', '2026-06-10 13:27:04', NULL, '45533aa2b124e6547a3804294fcf3aaf', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DJZDDZ00BSA04B660RS7M', '06FB3DQEMTDHF8SV27AKAB8JHW', '2026-06-10 13:27:05', '2026-06-10 13:27:05', NULL, '0eb2faf91e36a4d37a8a3aa97a8edb71', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DKQQJ583944DG8561VQ3G', '06FB3DQEMTDHF8SV27AKAB8JHW', '2026-06-10 13:27:05', '2026-06-10 13:27:05', NULL, 'b329ff8925097a977f528e7e114d6055', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DMF20SYFDT6WX2RFBQXKW', '06FB3DN94MBCTYJW17ZCYVSXE0', '2026-06-10 13:27:08', '2026-06-10 13:27:08', NULL, 'f494f6efad2377e6fc6d0bbf7ae35f07', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', '06FB3DN94MBCTYJW17ZCYVSXE0', '2026-06-10 13:27:09', '2026-06-10 13:27:09', NULL, 'e5d02fc3a99106d29a9ce6af0626f68e', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DMF20SYFDT6WX2RFBQXKW', '06FB3DNQZKV20F7YG5PJH8V8SM', '2026-06-10 13:27:09', '2026-06-10 13:27:09', NULL, '1d5185ae9c9676bd70d0e02e3a5e79a1', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', '06FB3DNQZKV20F7YG5PJH8V8SM', '2026-06-10 13:27:10', '2026-06-10 13:27:10', NULL, '90dca94aa700c143290b2b1afaca09ed', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DMF20SYFDT6WX2RFBQXKW', '06FB3DP48FS33CQGRDF7EB9GT0', '2026-06-10 13:27:10', '2026-06-10 13:27:10', NULL, '9b9081edc77f0e9a4b689bbc191771db', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DJZDDZ00BSA04B660RS7M', '06FB3DQEMTDHF8SV27AKAB8JHW', '2026-06-10 13:27:05', '2026-06-12 01:11:12', NULL, '17f1c884268a172f803f407a2ad47c8c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', '06FB3DN94MBCTYJW17ZCYVSXE0', '2026-06-10 13:27:09', '2026-06-12 01:11:17', NULL, 'a67368ff15089dce57838840632fe07e', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', '06FB3DNQZKV20F7YG5PJH8V8SM', '2026-06-10 13:27:10', '2026-06-12 01:11:22', NULL, '0ec8ff6c455136e45fbb1d06a2a690f1', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DMF20SYFDT6WX2RFBQXKW', '06FB3DP48FS33CQGRDF7EB9GT0', '2026-06-10 13:27:10', '2026-06-12 01:11:26', NULL, '3c985828c591c88d492eb261c6d26d33', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', '06FB3DMF20SYFDT6WX2RFBQXKW', '2026-06-12 01:11:31', '2026-06-12 01:11:31', NULL, '81fd318a43138a3bef82e31f928ff0b2', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMV7Y13PAYKZC0WB4FQXKC', '06FBKMXSVCE98K1H76N00TYCQR', '2026-06-12 03:16:35', '2026-06-12 03:16:35', NULL, '28d9785a1f9696b6b579a1dbb9fdb889', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMV7Y13PAYKZC0WB4FQXKC', '06FBKN09R21H3AWR2Q2ZTSGNSW', '2026-06-12 03:16:40', '2026-06-12 03:16:40', NULL, '7e00348c10432c65b03f9dce36520e48', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMXSVCE98K1H76N00TYCQR', '06FBKN2MP35NPPK1BRDYY2M428', '2026-06-12 03:16:44', '2026-06-12 03:16:44', NULL, 'a6b1c20279ac30f692a30c802cf8f3e5', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMV7Y13PAYKZC0WB4FQXKC', '06FBKN4QVFVE51MY2N0CWCVXHM', '2026-06-12 03:16:49', '2026-06-12 03:16:49', NULL, '9063328f18ba32c0737997ac9af0911a', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSM0PRGYR61R0NWYAT9VDC', '06FFW49VYMPF18PYQXD9PCMHN8', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, 'a5146a3cfb2f6a3fd904224150836336', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', '06FFW49W3V175EM4F8ZHC6JFM4', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, 'd57042b235b73ed2d25252d5253e6e4a', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', '06FFW49W6GP535GR8XD1XEHYWG', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, '07fe1945cb3e60c43cce0989366af8fb', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', '06FFW49W95HJK08BCRQSWFZBF4', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, 'e4484230e2202044baaa5ce7a2438bbb', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W3V175EM4F8ZHC6JFM4', '06FFW49W95HJK08BCRQSWFZBF4', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, '24cc5602737e75d30377522f38b3e7b5', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W95HJK08BCRQSWFZBF4', '06FFW49WBTT3ESK6QG0XZ1VN2G', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, '51f4759153b30d2a62ed6c69ab62b84d', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', '06FFW49WEE5N4PESF5G1G5JRHR', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, 'b348cfc357b73fb28366459795752d8b', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W95HJK08BCRQSWFZBF4', '06FFW49WEE5N4PESF5G1G5JRHR', '2026-06-25 10:24:38', '2026-06-25 10:24:38', NULL, 'e114eff56fef8c92fe3b19df2b8b6e3c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQ789MDB00EQAXTXBVJDXM', '06FGSQ8B7WDKZ174GJDGWW0GS0', '2026-06-28 06:14:17.763', '2026-06-28 06:14:17.763', NULL, '973169c6f426d9b4bcfd925ce0f36f32', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQ8B7WDKZ174GJDGWW0GS0', '06FGSQ8YSZA5YNP1JE8SJHXWBG', '2026-06-28 06:14:17.799', '2026-06-28 06:14:17.799', NULL, '60769ef20f951c01c5d20f512913b946', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2AD3HPR3HXSVASVZEX8PK0', '06FB2ACSDBDZARV3NNGYD9NYYR', '2026-06-28 13:28:39.768', '2026-06-28 13:28:39.768', NULL, 'd5a7084fa717846475fad88d8f30febd', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB234WP4Y6Q16A0HFW8BSXMG', '06FB2ACSDBDZARV3NNGYD9NYYR', '2026-06-28 13:28:39.808', '2026-06-28 13:28:39.808', NULL, '79027c30d19f6f7d43c3068fd80ba8ed', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ETJQP0CT6X7W3CWZ6NS9G', '06FGX26B0NAC9WRJMVB0QE6CV8', '2026-06-28 14:01:13.773', '2026-06-28 14:01:13.773', NULL, '68cfce9178bbb310b87c76a908781c76', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2ETJQP0CT6X7W3CWZ6NS9G', '2026-06-10 11:12:20', '2026-06-28 15:29:40.913', '2026-06-28 15:29:40.913', '16d8a936aa3083cd16ca25a57a2e1b86', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ETJQP0CT6X7W3CWZ6NS9G', '06FB2ERREMEEF26KKHGNZBWW64', '2026-06-28 15:29:44.904', '2026-06-28 15:29:44.904', NULL, '545d2ce4f863fd5bb2eee240b696be0c', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB234WP4Y6Q16A0HFW8BSXMG', '2026-06-10 11:12:11', '2026-06-28 15:29:57.491', NULL, '6e43179e6b211be30766ca56f5ed5885', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FB2AD3HPR3HXSVASVZEX8PK0', '2026-06-28 15:30:00.399', '2026-06-28 15:30:00.399', NULL, 'e0961be9550747530f530a7fd300583f', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', '06FGX26B0NAC9WRJMVB0QE6CV8', '2026-06-28 15:30:03.803', '2026-06-28 15:30:03.803', NULL, 'fa47a4a4aff706215efa3a449681d18f', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', '06FB2EV29HSK6EJ5VF50R87VC4', '2026-06-28 15:30:10.567', '2026-06-28 15:30:10.567', NULL, '52cd02f3a176cd078db479ef850cbcf4', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYPJ6FTEPP4JK3D7D01ZSMM', '06FGX26B0NAC9WRJMVB0QE6CV8', '2026-06-28 17:50:13.767', '2026-06-28 17:50:13.767', NULL, '3e0ac1d814ac13a12b68714c7320075f', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
|
INSERT INTO ticket_deps (blocker_record_id, blocked_record_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', '06FB2EV29HSK6EJ5VF50R87VC4', '2026-06-28 15:30:10.567', '2026-06-29 21:58:13.907', '2026-06-29 21:58:13.907', '3b7ec3277f971c3646a7587b06606335', 2) ON CONFLICT(blocker_record_id, blocked_record_id) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_deps.updated_at;
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
-- Auto-generated by pql init. CREATE TABLE statements
|
-- Auto-generated by migrate-ids (D-26). CREATE TABLE statements
|
||||||
-- for the planning schema; per-table dir keeps the changelog
|
-- for the planning schema; per-table dir keeps the changelog
|
||||||
-- self-describing per D-15. CREATE TABLE IF NOT EXISTS is
|
-- self-describing per D-15.
|
||||||
-- idempotent so running schema files from each directory in
|
-- pql:created_by: migrate-ids
|
||||||
-- replay order is harmless.
|
-- pql:canonical_version: 2
|
||||||
--
|
|
||||||
-- Importer parses the markers below to detect schema drift
|
|
||||||
-- between the producing pql version and the local one — a
|
|
||||||
-- bumped canonical_version means projection rules changed
|
|
||||||
-- and replay must refuse rather than silently corrupt state.
|
|
||||||
-- pql:created_by: 1.4.26
|
|
||||||
-- pql:canonical_version: 1
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS decisions (
|
CREATE TABLE IF NOT EXISTS decisions (
|
||||||
@@ -43,14 +36,23 @@ CREATE TABLE IF NOT EXISTS decision_refs (
|
|||||||
PRIMARY KEY (source_id, target_id, ref_type)
|
PRIMARY KEY (source_id, target_id, ref_type)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Identity split (D-26): a ticket's stable, collision-proof identity is its
|
||||||
|
-- record_id (a locally-generated ULID, planning.NewRecordID); the friendly
|
||||||
|
-- T-NNN label lives in ticket_idmap and may be reconciled. Every structural
|
||||||
|
-- reference (parent, deps, history, labels) targets record_id, so a label
|
||||||
|
-- clash never corrupts the graph — only ticket_idmap needs a relabel.
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
id TEXT PRIMARY KEY,
|
record_id TEXT PRIMARY KEY,
|
||||||
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
||||||
parent_id TEXT REFERENCES tickets(id),
|
parent_record_id TEXT REFERENCES tickets(record_id),
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'backlog'
|
-- No CHECK enumeration: the ticket status vocabulary is per-vault
|
||||||
CHECK(status IN ('backlog','ready','in_progress','review','done','cancelled')),
|
-- configurable (ticket_statuses in .pql/config.yaml). Validation lives
|
||||||
|
-- in Go (planning.StatusSet), so adding/renaming statuses needs no
|
||||||
|
-- schema change. The DEFAULT is a harmless fallback — CreateTicket
|
||||||
|
-- always inserts the configured default explicitly.
|
||||||
|
status TEXT NOT NULL DEFAULT 'backlog',
|
||||||
priority TEXT DEFAULT 'medium'
|
priority TEXT DEFAULT 'medium'
|
||||||
CHECK(priority IN ('critical','high','medium','low')),
|
CHECK(priority IN ('critical','high','medium','low')),
|
||||||
assigned_to TEXT,
|
assigned_to TEXT,
|
||||||
@@ -63,19 +65,33 @@ CREATE TABLE IF NOT EXISTS tickets (
|
|||||||
canonical_version INTEGER
|
canonical_version INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- ticket_idmap maps a record_id to its current friendly label (T-NNN).
|
||||||
|
-- ticket_id is intentionally NOT globally unique: two uncoordinated clones
|
||||||
|
-- can mint the same label, which surfaces as a duplicate-label collision
|
||||||
|
-- (detected at replay) and is fixed with "pql ticket relabel".
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_idmap (
|
||||||
|
record_id TEXT PRIMARY KEY REFERENCES tickets(record_id),
|
||||||
|
ticket_id TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_deps (
|
CREATE TABLE IF NOT EXISTS ticket_deps (
|
||||||
blocker_id TEXT NOT NULL REFERENCES tickets(id),
|
blocker_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
blocked_id TEXT NOT NULL REFERENCES tickets(id),
|
blocked_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (blocker_id, blocked_id)
|
PRIMARY KEY (blocker_record_id, blocked_record_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_history (
|
CREATE TABLE IF NOT EXISTS ticket_history (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
field TEXT NOT NULL,
|
field TEXT NOT NULL,
|
||||||
old_value TEXT,
|
old_value TEXT,
|
||||||
new_value TEXT,
|
new_value TEXT,
|
||||||
@@ -89,14 +105,14 @@ CREATE TABLE IF NOT EXISTS ticket_history (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_labels (
|
CREATE TABLE IF NOT EXISTS ticket_labels (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
label TEXT NOT NULL,
|
label TEXT NOT NULL,
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (ticket_id, label)
|
PRIMARY KEY (ticket_record_id, label)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS meta (
|
CREATE TABLE IF NOT EXISTS meta (
|
||||||
@@ -109,6 +125,8 @@ CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
|||||||
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_record_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ticket_idmap_label ON ticket_idmap(ticket_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
||||||
|
|||||||
@@ -1,483 +1,161 @@
|
|||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'backlog', 'ready', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '66d7c49f6b2ccdd2ef88a635ec717ca2', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'status', 'backlog', 'ready', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '3fba5e751d6a8c9a29335cad1550fa0f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'ready', 'in_progress', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '87c83225076b22ecbc7fd150b8ccce5f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'status', 'ready', 'in_progress', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, 'c4cb4ad45703aa943016359dc46469e8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, '056f21749ff40c14feeb380b2425bb04', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'status', 'review', 'done', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, '146a823b003c92bcd8b8f7e74f2f9f39', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'review', 'done', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, 'a345d1db748f86fb707b715ce4f45c82', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, 'bbf575b4892c07075dd436e44e65b2cc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:12', '2026-04-22 11:46:12', '2026-04-22 11:46:12', NULL, 'd666982c7578a64cff619807467b0d22', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KX7HEQJ65HZ566DG', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:12', '2026-04-22 11:46:12', '2026-04-22 11:46:12', NULL, 'f5088eafcad461a9a4ee4b4df88357d2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:16', '2026-04-22 11:46:16', '2026-04-22 11:46:16', NULL, 'bf092de792c1dba0a724e6c3ef0a2ca3', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KX7HEQJ65HZ566DG', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:16', '2026-04-22 11:46:16', '2026-04-22 11:46:16', NULL, '556eba472e2de76accea58ee559ce7d2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:26', '2026-04-22 11:46:26', '2026-04-22 11:46:26', NULL, '6648704125e10ddf9582b0fc8a91cbb8', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KX7HEQJ65HZ566DG', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:26', '2026-04-22 11:46:26', '2026-04-22 11:46:26', NULL, '3a17808cf45fab2b987da0d0cbde98b6', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'review', 'done', NULL, '2026-04-22 11:46:33', '2026-04-22 11:46:33', '2026-04-22 11:46:33', NULL, '28a5fbab4db244d0cc5c48e7e320ec71', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KX7HEQJ65HZ566DG', 'status', 'review', 'done', NULL, '2026-04-22 11:46:33', '2026-04-22 11:46:33', '2026-04-22 11:46:33', NULL, '2b09b099a97c35e26f35ac37228e9411', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '8e8f387c6cf81e8db06c212be3c75ff7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M1VZ8Z2SZ94F0EQR', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '0492e38c415358802970cb077447f7d7', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b0d4dd5c1779606c861d1fd778ee9d0f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M1VZ8Z2SZ94F0EQR', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '1ed839ad770ebbffdf23364dbcb766eb', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'review', 'done', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b93dd369ad1260e6b1f74798544bafd1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M1VZ8Z2SZ94F0EQR', 'status', 'review', 'done', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '4f52a76829285f14e71363d162c600e3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'e5b9592394cabd32ce426a3916c27827', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M1VZ8Z2SZ94F0EQR', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'efda926413d09bbd05a1c88275fc927f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'review', 'done', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '140ed6257373fb7d199c67da8452bb82', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GSR5WPC2T7CJM8XW', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '0c904f00c761b272e945045651b3c405', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '20cb7969c9c3af6a6deb93ee56a3a8f6', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GSR5WPC2T7CJM8XW', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '0f7b405a869b6c6d17bddd2189c5b52f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '456c32193f208cb4dcd78d722c8e5308', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GSR5WPC2T7CJM8XW', 'status', 'review', 'done', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '46d21523224743c31eb97a3c1e18d2d9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '92282e57e514c08df603650c82fc5ad1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GSR5WPC2T7CJM8XW', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, 'a33b066448c87f7be0542d61dfad5f66', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'review', 'done', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '2352d517e219af8edf4537f4145b5a9e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XZA5399D2EHYCVFC', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '061a7151be46322c0128980c073356df', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '37b7881534e16c2f369cdfb4a25ac511', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XZA5399D2EHYCVFC', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '08480dd43012f8f6f37e212767d26be2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '7e4e0f286bd3bf1687cbbd49fca9e1f4', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XZA5399D2EHYCVFC', 'status', 'review', 'done', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '7c004a225b6b82840101504aef4e758c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, 'c6ccbb7da6b303b5fd6ef4f5273c7d07', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XZA5399D2EHYCVFC', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '905c9d2df79619009b56009d193aa952', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:52', '2026-04-22 11:46:52', '2026-04-22 11:46:52', NULL, '99d159170d35cb6225a0b9e6f8e5a4f5', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7DV4ZS010XWZJ9A84', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:52', '2026-04-22 11:46:52', '2026-04-22 11:46:52', NULL, '9cafe6c3de8d9f5a3db8321ac7bcbafc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '171dab623718a0cb2a4af914c84e0d30', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '11c89804420370461fbd8fe880758f7e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '206793ce446e6ba302f209cda04dcb78', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '36f16d47e4acf599d2d78933bcc03c77', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '2a311168aab1126eadcb2e23433ba317', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '4162b254ba6ddb4daa8e85e428c5608c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '3098b6064c8b96eb459c5ed947ca97c4', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '45a71ef6bad527950f92d9323c3edf0a', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '366f83e624514e442d539f704a0abbb1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '477dc88ff367b8a6bd393711a9dc934b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '36c5d3bbd5f027fdb114391abdf1dda6', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '5d92aa65816538906b0cc1ed5ee87ed3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '381444444f3e04024e2293f61c774d1d', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '6b742f381bb7a072b02dfc55db62447f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '46d32785bb5113ebcb050845e67ea280', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '9842cfa577a4dc7eaf6792266bb365be', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '5fde942d02640b9df4e75d1d745b2de5', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '9dd7f0c00d8c7e3c7a67abaa8412bec9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '74dbfcfee3f60d46ba6e910ebb5fed1b', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'c557f84b4744487609e7ffb02fd2ed49', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '7d19553f3714932803e565e8ac106220', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'cd7a68edc46c277c49fa5839990504ad', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '9de91c0384a97d66eaa01e7f8164f389', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'd387e7910739e3ecc6702b51f0d8b9e4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'c257d281cc9fc54be99fea49688ff720', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'e1d3d1a9ca033dd1d334d478c8802e32', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'cf47b1a47c543dabd8fe0c891c535285', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'e4253f407304ff571299945fabe31eee', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'd34d4be4170d93183c18754a60ea97e1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'f22005f7ae58243f1fce0b07e6475235', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'db0af7f083e8985026799a9d3334347d', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'feb8a00523b7118d285847f7d88e70d3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '1a24e0b9fbc1472aacf17392a9241b99', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '4bad0ff51702836a574ecb8afb5bd47e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '7774f4c92e18371341b7c0332022d29a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'e64eeea1f1fcbea7c020191e6c94303d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '8589b12b48657f3513e801cd96dab11c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7DV4ZS010XWZJ9A84', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'e767c59bd07f4ceb3dabbbbd9a8b25dc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '92508b82168bd20d5a69c63a66271c34', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'f32b33eaddf68e8213bfbe698960da29', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'dc2b5b3b5b348409f6d719f05130804b', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'feb5c5a54317cafb1ca8d77ba93cc81e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '0dd7c9716ba7dab383c7890822ba9224', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '08373a38596647969ebd74504544616a', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '23c19fa354da9eb201212b23696da027', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '3a7ee18edc398147113c0ab45b4812eb', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '79e01d297b5cf559d37f2c0ee3661a51', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '5adac012531c1b1f400ecb2290782e5b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '88a0fb2513eebbd4627abd854eefb484', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '7952677f8c48b6dc6e9c6e05a78e80a8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '9ad3112f08548b5896fd2252dda48be0', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'a545724b00ae8c2f2b9ea09cb0a22eb0', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'acba548461502b88a483649f181a65da', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'ba68ce26a31c4bc0c56d5dcf1640b6e9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'bd986c8233a7a251c0403c4df3ce8511', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'c1a7e08caf95080e168df4e611dba0d7', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'cfb6a1faab0ce219609f44055648cda1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'c97eb916069dd8267e623872edcd7452', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'dabc0f13943decd855d39febfd2a18ae', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'd520ce983ac294f25f96da3e22fe2257', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'e340923ef96f70f142a0bee868bb8e67', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'db6a409471d1fcf96494fca0cf36b950', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'f179c71abcd89f7ed9fa781220d2018c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'eabc93b76de154cf79976608c0d00603', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'fae80bffb40c02fdf07691ef18837b14', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'ed6fc64e88ca1dc9065e72ebd6067e4d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '1693e0a6448fb98bd03fe0c4c65371fb', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7DV4ZS010XWZJ9A84', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '11f427298c60d6f583daa698b0b54e37', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'review', 'done', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '80d695ac3bfc5fe1f3615013dea3b06a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7DV4ZS010XWZJ9A84', 'status', 'review', 'done', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '8a18fc5ed3fbf30e4abddd0cfe100bff', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '33a14771999bc0062268447b4ffadc73', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '74a219dafd7350205cac9eeda53552c2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '5a2f1c3d37090ad5791c6a0e8a7aa80a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'e7e1a901f6e799c0eae79c9dc2bb4a33', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '7d84a743a1b9e1ce5c50172b89318153', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'ec16cf36360eb2a7805bffed1a243ecf', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'cad02006950fb6fa0d003553437d3bbe', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'f49e07cca55f982a6a07162f55c0c6d8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '10f0a16fa4e4899c7817dd5c44cc3ffe', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '127e63f3c290f90e7c3aa847afd24923', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '2d697a30a6193eacf2a3ddf1661e861c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '488736bebe779b1281384ce5765a883e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '591bb27186744d023df34105884fa58f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '76d283c661ddda877270447bf9ed3b0b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '817b9d8e92707eb588cb7f9eae7d424e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '8108195e0776ff2e2493720ef80c5b6b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'status', 'backlog', 'cancelled', NULL, '2026-04-22 20:34:17', '2026-04-22 20:34:17', '2026-04-22 20:34:17', NULL, '5460d369f6cdef9c393a37e41481bcb5', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6PMW57C70KBJVAV10', 'status', 'backlog', 'cancelled', NULL, '2026-04-22 20:34:17', '2026-04-22 20:34:17', '2026-04-22 20:34:17', NULL, '66eac257c948b529c5949d17ca5f1d11', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '313d4c9dd6444a4573cbe9584ed18f61', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4VVHNKNXPYD4XWRYW', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '2031b1358057b8fad868649bb7484500', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '4630269c56784316b975ca56b10a2337', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GHHRANK5532VJVJR', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'a46451df6d3b67e3bcfbf48bb73c2e12', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '5a8f7e0eda55bc0893c6597400a8d535', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM64DC28XV20JJ8KW00', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'c397fe7de79cc82035f57a5cdaa2b83d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'fac6b818dc68490a80ea32255f0ba404', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WXV1RKPDK810C3FR', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'd471b281adf859311624bb19452d36ba', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '0a7137f82fbb9307496b7e4133b15052', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WXV1RKPDK810C3FR', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '154c84814ce1eacfd09580762e35748e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '5aff1ed40d9a68a5b4d59aab0d24dd31', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4VVHNKNXPYD4XWRYW', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '2a3c5b0f2799072f0c593128ac99ddec', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '931bcaabbd64af0612fbe6eb9a4470d6', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM64DC28XV20JJ8KW00', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, 'e78fe6d9079f625573cf0993bb73a684', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, 'c2fca20d28b2a3a63a56eb2841a4bda9', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GHHRANK5532VJVJR', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, 'ffade557a91afb2ce8d223a59c987d15', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '84e5b99f4fb99f8ae4d189ddaac2de74', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GHHRANK5532VJVJR', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '0ad715f5bfdec4a3c8005f0f4cb857d6', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '8c7ba0fd4c8acc6065a24b80ae28d526', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4VVHNKNXPYD4XWRYW', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '4cd3af18c76884911ac0eff87f93e4c0', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'd91c6440f66e683a87be5e61a366cca7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WXV1RKPDK810C3FR', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '870fda31d4fbd8c39e4a6ed78551a089', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'f9253848d9a95ce1823c8ba78a511fc0', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM64DC28XV20JJ8KW00', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '92206091799f820dd2ae2778a92947fc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '389d5abb35b3b73ccb38ac8bec3b92c7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4005W4QV0ZPBMQ02C', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '0798cec4e8ce91238498218a90fc2b4e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '7e714e95f89966a13e436d2fe38e7443', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4005W4QV0ZPBMQ02C', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '4d677f10ac70a801bc5d691e618dd098', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, 'b1aa8ff1f9b24cdfc9e0bebf21d38b99', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4005W4QV0ZPBMQ02C', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '79fde318878ec91f2cd020be9db706c4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '39b407be88dbb31f530c8074f6bcecc7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7MKCHC37G69SJGQ04', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '615893bb4159bca57088c5a8e202e834', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '59df9c23d722ccf1c1ac18baee76c785', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7MKCHC37G69SJGQ04', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '7350f6584bee9eeadb6a41001f34876b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '76b48a80abcba29b1047c794fd004234', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7MKCHC37G69SJGQ04', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, 'a4994cbb075a8921e4d0d505d922981c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '297763c026010189ea0bd870f77a173e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KH7VR0BMZV5SSTXC', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '114825918ccc9039ad4653dc5c3b5785', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '2cd947436be1c156eb77d233aeed5da2', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6JXWYYQ6MT6N8STYM', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '1bc4adcc9db4ab023130198ed8299bb4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '38826870354a1bf51bc2ff21f6da0ea3', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5Q6AWSTKGT0P64TRR', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '2c6e445be22794878bd6784a5973c028', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '5105038efff2e3055213b1b1403b7610', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KH7VR0BMZV5SSTXC', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '307d5b39c6fe3df3d2a620a591d7d5c8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '67cc6c0934711b6a592e11e5edc6194c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5Q6AWSTKGT0P64TRR', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '798c86f77cdd2b3a1a337291215b45d6', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '6e9e7d3ce9f74ed261912b1cb099dcad', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6JXWYYQ6MT6N8STYM', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '81141b1ca5d1d6ba526b33054189ebfa', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'a4e702776f3b553fb276782e539ebfc7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6JXWYYQ6MT6N8STYM', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '83e47e7c7550ce0f3c724edfa773016f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'd294248ba8ea651e78aeb6fed0457eb4', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KH7VR0BMZV5SSTXC', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '8b6ef7ffc9b872edbe8ccd513f0a239e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'da8dc2002a03eaee7fcd5504abee6f60', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5Q6AWSTKGT0P64TRR', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'c040aca52959ae8febda5e0dd54252a2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '08f09f3bb9f1a0001110716930824e62', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '007710b30c9e75b030b44dba9fa5f824', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-29', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '10005b4803d743aa21be0223c8a85d5c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '0c80d9ff14fd5992b92f0c9b8b9eb647', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '11ac23b546d0e22206af4221062f5912', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '18e5b09f781d974d4746fa984734872f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-21', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '127404fe79dfb79d0297b85d78235c68', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67JSC5RKS6M9182KG', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '1fbe35313558f6277b818cff665009a9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-23', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '15fb6606af61e11b6960799721e7cdcc', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5YG22EV7BFTX5RTPR', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '20d5c46249f5b8810e17914929ec763e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '19f6209ce4428172fb16941accb13566', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM699HAWC76SHRA7AM4', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '251327841ab9971717b36c2cb79ca299', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-27', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '212224b7dcc4b991119dc430ae179311', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '2e3916450f98a766aac0c2abc301e6c4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '2fe8eed15b3ead999a69cdd08df5e14c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5E41Q8TX8X55X4MZ0', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '4502258c81a7e75eafd3631e0cdf90b8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '3990623d651c604fec692edb70976d69', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67ZXPWX71ND4C699C', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '4c190ec1739ed8ec68fe694687fa5fe3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '44d273b92ad4c93159706c1f17fcb6a7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JK0RHMRAH47K8ND4', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '4ca23526443704936c352c2842f2f7f8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '46935c5a6d8ef12cf1c2252bd8d30368', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5KYAV8TMH3Y3FPRSR', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '50dc074f7f06d51e11fee8d00dd7dd74', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '551ea05a8d0cc28c0ff7010a139e6fe1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '6a700a972bd1c1a0729bf27078def56f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '6748fca610fc8a8503d69846231616fe', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5Q6AWSTKGT0P64TRR', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '773e27abfec30eeb016b441c1dc0d8f8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '7843cfda82ec1c1622c1a201f82acaf1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '881064c3f6f63638a754929f1078b011', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '822790bbace926feb2372b8665080932', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9404bff31ca5c310db47f5c0e11c90ca', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9a1ae5742a1230e60279d9c72f8b0f75', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48MDE8ZZ82VWNY994', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '96cf4f78cd06636178ba9a64d6b83f2d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-42', 'parent_id', NULL, 'T-5', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a414bc8e4d32fa32483228a4e9c7be8c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9b17afe084710d3e198c7435ee0fb4b6', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-24', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a80caae1913b8e9a1d5dab980bf0b77b', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6RDM2EKZX132GPV7M', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9ca8eb0c58afc81c07a7538b8e504ad4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-40', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a895d51a2e6e8b448684933cf0224162', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM66TK8TQ1X5T9GK6V0', 'parent_id', NULL, 'T-5', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9f69eaa0855cbea3a8e715b7bb917624', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ad9a8a85686e33df17ae15631afa1213', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6PMW57C70KBJVAV10', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b683b61fdb656a5f6df871190736771f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'aedb3c83402245f81cd10f04d15dcf8e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KH7VR0BMZV5SSTXC', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'c27a712580912bc125013ca9ee3330a1', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b6dbb8114cd77c206d3b8bdf054736b9', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4005W4QV0ZPBMQ02C', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'cca49092a5f8f1912acd35c168101148', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-26', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b7b189fe87f61d42e1d0318d23aeb1fe', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4M63G18VAQFG6R3XW', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ce9352bab1e00b12f8ff794fca067732', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'c80049d2c236f0d2512355183b766f0f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'dc8745c0d7b3445b0c78985f1f9995dc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-25', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ccdf7bec2a75f5829eab4fdd57171622', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'e1831cbdaa2e3ce0000a590874c08a76', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-36', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'd13ed78c92d33e61e448c9e155adf870', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6JXWYYQ6MT6N8STYM', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'e5214fde5b73b4a7165107dc85057ec5', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-41', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'eb2a2ca41a57604b40556e81bf6480a9', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'e6649095b63a9a991df2db00a7ad53ca', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f0d27e423d40a998115e10ffd804f791', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4W194B2421P2SF83R', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ee6e9785f9f760ab2c6b3f689afefad2', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f5c891c9a5f7d5e3f43ded0dc07eb704', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5QHMB46NSHHPVQRF0', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f9b20bf38afe42bfdfd811ab282658ee', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ff609c22f964618c84b7c36988e87ae7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'fb24ffd20df49eb6febd496a6c1c02bf', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, '6ae864936d48565e880f06e984e9d978', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, '728ad0916172fb20a1c4b19d0753e4db', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, 'ebebc38301a28001a09c9e7066c9aeb9', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, 'bfd785a9e40e27979d287ec137ec01d1', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '3cf128b79fe91447f72f42d8cffce9e1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '3b1ea2037fa8d26c4293a2bd5d0fa007', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '68f57f5e3a1005ca3009f944b8b634d7', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, 'd5329907e937e55e00a9d002da5ac6d4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:40', '2026-04-24 07:05:40', '2026-04-24 07:05:40', NULL, '50aa3e362dbe9682d98f6d5f71ea97b1', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:40', '2026-04-24 07:05:40', '2026-04-24 07:05:40', NULL, '5a372aa4814812aa716d853550fea046', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:05:50', '2026-04-24 07:05:50', '2026-04-24 07:05:50', NULL, '4cb951c3ea697881d8fa5b0e86cfdf96', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:05:50', '2026-04-24 07:05:50', '2026-04-24 07:05:50', NULL, 'ba35f95ff2763f26ebccff21a2b826af', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:51', '2026-04-24 07:05:51', '2026-04-24 07:05:51', NULL, '7516ffa5c72fa4e7fd067249393c3653', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:51', '2026-04-24 07:05:51', '2026-04-24 07:05:51', NULL, '4e46180f02c86278deedd9f8f08d4d07', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:06:30', '2026-04-24 07:06:30', '2026-04-24 07:06:30', NULL, '268576bd9559485dd2ac5e7ffd1f1a79', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:06:30', '2026-04-24 07:06:30', '2026-04-24 07:06:30', NULL, '8e985069c3c5eeb6b172f83430458810', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:06:32', '2026-04-24 07:06:32', '2026-04-24 07:06:32', NULL, 'ef46c3a3db4c4ba50ff1f0e1baa4c0e6', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:06:32', '2026-04-24 07:06:32', '2026-04-24 07:06:32', NULL, '66c14397b8af87bceaace31b1dff2853', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'review', 'done', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '1cd74d47eb547aa0bef71597eaaa2c5b', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'review', 'done', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '5733cc23693ca40190bd8c5063a7a022', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '3b8c17d366d1710d03523303c9df83c8', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'in_progress', 'review', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '9669c3ab67cb4477961d2ee3aa799a90', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'review', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '7eb9ca56292802301f93d0e2d680835e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, 'de6f0dd22f5f0e664793f74429322b8b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, 'a1a837494c047ade786d79edb75296dd', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, 'e7b5b2d4e43d09ede3d177528718683a', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:00', '2026-04-24 07:08:00', '2026-04-24 07:08:00', NULL, 'ac745b5254a0e8f085189c23d95acb7e', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:00', '2026-04-24 07:08:00', '2026-04-24 07:08:00', NULL, '976f8fecced9b5322ed3403b8fbdf0dc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'done', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, '2adaf942a49bfeeac90aee1527a98444', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'in_progress', 'done', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, '281fe02b5f9467e50e0a186fc1afb77c', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, 'e0d54ffba34677dc6e687be801ccec05', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, 'fd27037a9f94cf0df10016ff2c3b6e78', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, '74e6fa2f524c21300467381c2f3ad4e3', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, '52ed48f7463c234efeb35fcf45957e8a', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, 'fbd19eabf442e6e0de60028c28956b8f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, '8fb22a82912e93b9abff0da33d371093', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '7d3efe4ccaee7d45d1a01d28144c4f0a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'backlog', 'cancelled', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '3e65f78d186b37308165679295b40408', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '914a2f5f5ef0807a6743f8811e71804b', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'cancelled', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '5b81f1c8048cd2b3ef1055ac9b04f958', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'a1cd74c76fd10c353aa758cea0331c5c', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '7348283db8af7104b475d0d84a0a7157', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'cancelled', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'cdbe85f80838e781048780db934d0115', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '804f233159ce47a2c213778971fc00a1', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'cancelled', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f24e8d138172597d7ddcf26672b67d5f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '91171fb011294517240bd33360b08119', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f9a83fa1b41d56202c57e6a55b240f35', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'd0b87332faf5a67e7e6d36ff9c981c00', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'done', NULL, '2026-04-24 07:30:15', '2026-04-24 07:30:15', '2026-04-24 07:30:15', NULL, '99c4e5a68463201e7f1b7764eddfd2ae', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'backlog', 'done', NULL, '2026-04-24 07:30:15', '2026-04-24 07:30:15', '2026-04-24 07:30:15', NULL, 'bf086ebf2d4e6b0a592f8386e916115b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'done', 'backlog', NULL, '2026-04-24 07:30:22', '2026-04-24 07:30:22', '2026-04-24 07:30:22', NULL, 'd0274058b130d8003123881b8a410f7f', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'status', 'done', 'backlog', NULL, '2026-04-24 07:30:22', '2026-04-24 07:30:22', '2026-04-24 07:30:22', NULL, '8e29783cc997d80b6699bd14537e8613', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, '83d70eb5a7f6e7175e0719fdb23243c2', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, '1bc6c7c959742697cd8670771ebeb8d9', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, 'b5acf95cb059f0c573b78d755b938da2', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, '51a117e3e688d86d72e33a844dfb6217', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:23', '2026-04-24 08:08:23', '2026-04-24 08:08:23', NULL, '4ae08b8af459af0679b05cf1f8ac3950', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:23', '2026-04-24 08:08:23', '2026-04-24 08:08:23', NULL, 'bf1f3a13e6bc7df6adf20b545e6911aa', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:08:38', '2026-04-24 08:08:38', '2026-04-24 08:08:38', NULL, 'c7e4cabf5d1fccad28f22d498e91193a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:08:38', '2026-04-24 08:08:38', '2026-04-24 08:08:38', NULL, '66d52940767ba7c91f848431ee618ba1', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:40', '2026-04-24 08:08:40', '2026-04-24 08:08:40', NULL, '9b0937bc7eb82785407c367a90365c3a', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:40', '2026-04-24 08:08:40', '2026-04-24 08:08:40', NULL, '1154f797d2c87e3e5aff6c8407b97f7e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'review', NULL, '2026-04-24 08:08:44', '2026-04-24 08:08:44', '2026-04-24 08:08:44', NULL, '90587f61d96b12ce53f2a4edc705fdd8', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'in_progress', 'review', NULL, '2026-04-24 08:08:44', '2026-04-24 08:08:44', '2026-04-24 08:08:44', NULL, '99a8c33d31f16025ad3a27305ec703a0', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'review', 'in_progress', NULL, '2026-04-24 08:08:48', '2026-04-24 08:08:48', '2026-04-24 08:08:48', NULL, 'd02ac7ee61fc4dc420fb7597a4f326db', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'review', 'in_progress', NULL, '2026-04-24 08:08:48', '2026-04-24 08:08:48', '2026-04-24 08:08:48', NULL, '9475c2583b2f0d3742f792f5dcffd4aa', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:16:15', '2026-04-24 08:16:15', '2026-04-24 08:16:15', NULL, '145613c94b4366bda03fb76c0f0747ce', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:16:15', '2026-04-24 08:16:15', '2026-04-24 08:16:15', NULL, 'df08122765cc76b0003b6e9ff54426fb', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:16:19', '2026-04-24 08:16:19', '2026-04-24 08:16:19', NULL, '0d8e318e8060aece6e18788cee56f646', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:16:19', '2026-04-24 08:16:19', '2026-04-24 08:16:19', NULL, '4e273f400ffcfbf2bc926ee4e9575fbc', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:16:21', '2026-04-24 08:16:21', '2026-04-24 08:16:21', NULL, '3d8635cfdbaf9b0c22dcba9f15f3c1ad', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:16:21', '2026-04-24 08:16:21', '2026-04-24 08:16:21', NULL, '6e750d5ebacc51f2734e94675322e5c4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:16:47', '2026-04-24 08:16:47', '2026-04-24 08:16:47', NULL, '77f873a7a5fff47ce9b974a6999d03b4', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:16:47', '2026-04-24 08:16:47', '2026-04-24 08:16:47', NULL, '9e82a53ad5b5d58037280a6778e335fe', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'status', 'backlog', 'in_progress', NULL, '2026-04-24 08:16:56', '2026-04-24 08:16:56', '2026-04-24 08:16:56', NULL, 'e7610d68ec9871746b4a361e33b18f05', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4M63G18VAQFG6R3XW', 'status', 'backlog', 'in_progress', NULL, '2026-04-24 08:16:56', '2026-04-24 08:16:56', '2026-04-24 08:16:56', NULL, '8a9247ea1de65f4696dc7af64a5d2b7f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:17:11', '2026-04-24 08:17:11', '2026-04-24 08:17:11', NULL, '9c3afbbfca207aeb78541dbd9d90e462', 1) ON CONFLICT(hash) DO NOTHING;
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67ZXPWX71ND4C699C', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:17:11', '2026-04-24 08:17:11', '2026-04-24 08:17:11', NULL, '38b265daee03a4df5fb525e48b477388', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'backlog', 'ready', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '66d7c49f6b2ccdd2ef88a635ec717ca2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'ready', 'in_progress', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '87c83225076b22ecbc7fd150b8ccce5f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, '056f21749ff40c14feeb380b2425bb04', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'review', 'done', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, 'a345d1db748f86fb707b715ce4f45c82', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:12', '2026-04-22 11:46:12', '2026-04-22 11:46:12', NULL, 'd666982c7578a64cff619807467b0d22', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:16', '2026-04-22 11:46:16', '2026-04-22 11:46:16', NULL, 'bf092de792c1dba0a724e6c3ef0a2ca3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:26', '2026-04-22 11:46:26', '2026-04-22 11:46:26', NULL, '6648704125e10ddf9582b0fc8a91cbb8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'review', 'done', NULL, '2026-04-22 11:46:33', '2026-04-22 11:46:33', '2026-04-22 11:46:33', NULL, '28a5fbab4db244d0cc5c48e7e320ec71', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '8e8f387c6cf81e8db06c212be3c75ff7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b0d4dd5c1779606c861d1fd778ee9d0f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'review', 'done', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b93dd369ad1260e6b1f74798544bafd1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'e5b9592394cabd32ce426a3916c27827', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'review', 'done', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '140ed6257373fb7d199c67da8452bb82', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '20cb7969c9c3af6a6deb93ee56a3a8f6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '456c32193f208cb4dcd78d722c8e5308', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '92282e57e514c08df603650c82fc5ad1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'review', 'done', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '2352d517e219af8edf4537f4145b5a9e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '37b7881534e16c2f369cdfb4a25ac511', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '7e4e0f286bd3bf1687cbbd49fca9e1f4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, 'c6ccbb7da6b303b5fd6ef4f5273c7d07', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:52', '2026-04-22 11:46:52', '2026-04-22 11:46:52', NULL, '99d159170d35cb6225a0b9e6f8e5a4f5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '171dab623718a0cb2a4af914c84e0d30', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '206793ce446e6ba302f209cda04dcb78', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '2a311168aab1126eadcb2e23433ba317', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '3098b6064c8b96eb459c5ed947ca97c4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '366f83e624514e442d539f704a0abbb1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '36c5d3bbd5f027fdb114391abdf1dda6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '381444444f3e04024e2293f61c774d1d', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '46d32785bb5113ebcb050845e67ea280', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '5fde942d02640b9df4e75d1d745b2de5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '74dbfcfee3f60d46ba6e910ebb5fed1b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '7d19553f3714932803e565e8ac106220', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '9de91c0384a97d66eaa01e7f8164f389', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'c257d281cc9fc54be99fea49688ff720', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'cf47b1a47c543dabd8fe0c891c535285', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'd34d4be4170d93183c18754a60ea97e1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'db0af7f083e8985026799a9d3334347d', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '1a24e0b9fbc1472aacf17392a9241b99', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '7774f4c92e18371341b7c0332022d29a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '8589b12b48657f3513e801cd96dab11c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '92508b82168bd20d5a69c63a66271c34', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'dc2b5b3b5b348409f6d719f05130804b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '0dd7c9716ba7dab383c7890822ba9224', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '23c19fa354da9eb201212b23696da027', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '79e01d297b5cf559d37f2c0ee3661a51', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '88a0fb2513eebbd4627abd854eefb484', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '9ad3112f08548b5896fd2252dda48be0', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'acba548461502b88a483649f181a65da', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'bd986c8233a7a251c0403c4df3ce8511', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'cfb6a1faab0ce219609f44055648cda1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'dabc0f13943decd855d39febfd2a18ae', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'e340923ef96f70f142a0bee868bb8e67', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'f179c71abcd89f7ed9fa781220d2018c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'fae80bffb40c02fdf07691ef18837b14', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '1693e0a6448fb98bd03fe0c4c65371fb', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'review', 'done', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '80d695ac3bfc5fe1f3615013dea3b06a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '33a14771999bc0062268447b4ffadc73', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '5a2f1c3d37090ad5791c6a0e8a7aa80a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '7d84a743a1b9e1ce5c50172b89318153', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'cad02006950fb6fa0d003553437d3bbe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '10f0a16fa4e4899c7817dd5c44cc3ffe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '2d697a30a6193eacf2a3ddf1661e861c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '591bb27186744d023df34105884fa58f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '817b9d8e92707eb588cb7f9eae7d424e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'status', 'backlog', 'cancelled', NULL, '2026-04-22 20:34:17', '2026-04-22 20:34:17', '2026-04-22 20:34:17', NULL, '5460d369f6cdef9c393a37e41481bcb5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '313d4c9dd6444a4573cbe9584ed18f61', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '4630269c56784316b975ca56b10a2337', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '5a8f7e0eda55bc0893c6597400a8d535', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'fac6b818dc68490a80ea32255f0ba404', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '0a7137f82fbb9307496b7e4133b15052', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '5aff1ed40d9a68a5b4d59aab0d24dd31', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '931bcaabbd64af0612fbe6eb9a4470d6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, 'c2fca20d28b2a3a63a56eb2841a4bda9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '84e5b99f4fb99f8ae4d189ddaac2de74', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '8c7ba0fd4c8acc6065a24b80ae28d526', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'd91c6440f66e683a87be5e61a366cca7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'f9253848d9a95ce1823c8ba78a511fc0', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '389d5abb35b3b73ccb38ac8bec3b92c7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '7e714e95f89966a13e436d2fe38e7443', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, 'b1aa8ff1f9b24cdfc9e0bebf21d38b99', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '39b407be88dbb31f530c8074f6bcecc7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '59df9c23d722ccf1c1ac18baee76c785', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '76b48a80abcba29b1047c794fd004234', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '297763c026010189ea0bd870f77a173e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '2cd947436be1c156eb77d233aeed5da2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '38826870354a1bf51bc2ff21f6da0ea3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '5105038efff2e3055213b1b1403b7610', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '67cc6c0934711b6a592e11e5edc6194c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '6e9e7d3ce9f74ed261912b1cb099dcad', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'a4e702776f3b553fb276782e539ebfc7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'd294248ba8ea651e78aeb6fed0457eb4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'da8dc2002a03eaee7fcd5504abee6f60', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '08f09f3bb9f1a0001110716930824e62', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-29', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '10005b4803d743aa21be0223c8a85d5c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '11ac23b546d0e22206af4221062f5912', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-21', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '127404fe79dfb79d0297b85d78235c68', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-23', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '15fb6606af61e11b6960799721e7cdcc', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '19f6209ce4428172fb16941accb13566', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-27', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '212224b7dcc4b991119dc430ae179311', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '2fe8eed15b3ead999a69cdd08df5e14c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '3990623d651c604fec692edb70976d69', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '44d273b92ad4c93159706c1f17fcb6a7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '46935c5a6d8ef12cf1c2252bd8d30368', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '551ea05a8d0cc28c0ff7010a139e6fe1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '6748fca610fc8a8503d69846231616fe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '7843cfda82ec1c1622c1a201f82acaf1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '822790bbace926feb2372b8665080932', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9a1ae5742a1230e60279d9c72f8b0f75', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-42', 'parent_id', NULL, 'T-5', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a414bc8e4d32fa32483228a4e9c7be8c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-24', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a80caae1913b8e9a1d5dab980bf0b77b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-40', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a895d51a2e6e8b448684933cf0224162', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ad9a8a85686e33df17ae15631afa1213', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'aedb3c83402245f81cd10f04d15dcf8e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b6dbb8114cd77c206d3b8bdf054736b9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-26', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b7b189fe87f61d42e1d0318d23aeb1fe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'c80049d2c236f0d2512355183b766f0f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-25', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ccdf7bec2a75f5829eab4fdd57171622', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-36', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'd13ed78c92d33e61e448c9e155adf870', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-41', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'eb2a2ca41a57604b40556e81bf6480a9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f0d27e423d40a998115e10ffd804f791', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f5c891c9a5f7d5e3f43ded0dc07eb704', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ff609c22f964618c84b7c36988e87ae7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, '6ae864936d48565e880f06e984e9d978', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, 'ebebc38301a28001a09c9e7066c9aeb9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '3cf128b79fe91447f72f42d8cffce9e1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '68f57f5e3a1005ca3009f944b8b634d7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:40', '2026-04-24 07:05:40', '2026-04-24 07:05:40', NULL, '50aa3e362dbe9682d98f6d5f71ea97b1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:05:50', '2026-04-24 07:05:50', '2026-04-24 07:05:50', NULL, '4cb951c3ea697881d8fa5b0e86cfdf96', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:51', '2026-04-24 07:05:51', '2026-04-24 07:05:51', NULL, '7516ffa5c72fa4e7fd067249393c3653', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:06:30', '2026-04-24 07:06:30', '2026-04-24 07:06:30', NULL, '268576bd9559485dd2ac5e7ffd1f1a79', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:06:32', '2026-04-24 07:06:32', '2026-04-24 07:06:32', NULL, 'ef46c3a3db4c4ba50ff1f0e1baa4c0e6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'review', 'done', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '1cd74d47eb547aa0bef71597eaaa2c5b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '3b8c17d366d1710d03523303c9df83c8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'review', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '7eb9ca56292802301f93d0e2d680835e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, 'a1a837494c047ade786d79edb75296dd', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:00', '2026-04-24 07:08:00', '2026-04-24 07:08:00', NULL, 'ac745b5254a0e8f085189c23d95acb7e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'done', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, '2adaf942a49bfeeac90aee1527a98444', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, 'e0d54ffba34677dc6e687be801ccec05', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, '74e6fa2f524c21300467381c2f3ad4e3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, 'fbd19eabf442e6e0de60028c28956b8f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '7d3efe4ccaee7d45d1a01d28144c4f0a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '914a2f5f5ef0807a6743f8811e71804b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'a1cd74c76fd10c353aa758cea0331c5c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'cancelled', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'cdbe85f80838e781048780db934d0115', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'cancelled', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f24e8d138172597d7ddcf26672b67d5f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f9a83fa1b41d56202c57e6a55b240f35', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'done', NULL, '2026-04-24 07:30:15', '2026-04-24 07:30:15', '2026-04-24 07:30:15', NULL, '99c4e5a68463201e7f1b7764eddfd2ae', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'done', 'backlog', NULL, '2026-04-24 07:30:22', '2026-04-24 07:30:22', '2026-04-24 07:30:22', NULL, 'd0274058b130d8003123881b8a410f7f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, '83d70eb5a7f6e7175e0719fdb23243c2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, 'b5acf95cb059f0c573b78d755b938da2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:23', '2026-04-24 08:08:23', '2026-04-24 08:08:23', NULL, '4ae08b8af459af0679b05cf1f8ac3950', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:08:38', '2026-04-24 08:08:38', '2026-04-24 08:08:38', NULL, 'c7e4cabf5d1fccad28f22d498e91193a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:40', '2026-04-24 08:08:40', '2026-04-24 08:08:40', NULL, '9b0937bc7eb82785407c367a90365c3a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'review', NULL, '2026-04-24 08:08:44', '2026-04-24 08:08:44', '2026-04-24 08:08:44', NULL, '90587f61d96b12ce53f2a4edc705fdd8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'review', 'in_progress', NULL, '2026-04-24 08:08:48', '2026-04-24 08:08:48', '2026-04-24 08:08:48', NULL, 'd02ac7ee61fc4dc420fb7597a4f326db', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:16:15', '2026-04-24 08:16:15', '2026-04-24 08:16:15', NULL, '145613c94b4366bda03fb76c0f0747ce', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:16:19', '2026-04-24 08:16:19', '2026-04-24 08:16:19', NULL, '0d8e318e8060aece6e18788cee56f646', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:16:21', '2026-04-24 08:16:21', '2026-04-24 08:16:21', NULL, '3d8635cfdbaf9b0c22dcba9f15f3c1ad', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:16:47', '2026-04-24 08:16:47', '2026-04-24 08:16:47', NULL, '77f873a7a5fff47ce9b974a6999d03b4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'status', 'backlog', 'in_progress', NULL, '2026-04-24 08:16:56', '2026-04-24 08:16:56', '2026-04-24 08:16:56', NULL, 'e7610d68ec9871746b4a361e33b18f05', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:17:11', '2026-04-24 08:17:11', '2026-04-24 08:17:11', NULL, '9c3afbbfca207aeb78541dbd9d90e462', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'backlog', 'ready', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '66d7c49f6b2ccdd2ef88a635ec717ca2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'ready', 'in_progress', NULL, '2026-04-22 09:42:11', '2026-04-22 09:42:11', '2026-04-22 09:42:11', NULL, '87c83225076b22ecbc7fd150b8ccce5f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, '056f21749ff40c14feeb380b2425bb04', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'status', 'review', 'done', NULL, '2026-04-22 11:45:21', '2026-04-22 11:45:21', '2026-04-22 11:45:21', NULL, 'a345d1db748f86fb707b715ce4f45c82', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:12', '2026-04-22 11:46:12', '2026-04-22 11:46:12', NULL, 'd666982c7578a64cff619807467b0d22', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:16', '2026-04-22 11:46:16', '2026-04-22 11:46:16', NULL, 'bf092de792c1dba0a724e6c3ef0a2ca3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:26', '2026-04-22 11:46:26', '2026-04-22 11:46:26', NULL, '6648704125e10ddf9582b0fc8a91cbb8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-2', 'status', 'review', 'done', NULL, '2026-04-22 11:46:33', '2026-04-22 11:46:33', '2026-04-22 11:46:33', NULL, '28a5fbab4db244d0cc5c48e7e320ec71', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, '8e8f387c6cf81e8db06c212be3c75ff7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b0d4dd5c1779606c861d1fd778ee9d0f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'review', 'done', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'b93dd369ad1260e6b1f74798544bafd1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-3', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:37', '2026-04-22 11:46:37', '2026-04-22 11:46:37', NULL, 'e5b9592394cabd32ce426a3916c27827', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'review', 'done', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '140ed6257373fb7d199c67da8452bb82', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '20cb7969c9c3af6a6deb93ee56a3a8f6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '456c32193f208cb4dcd78d722c8e5308', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-4', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:44', '2026-04-22 11:46:44', '2026-04-22 11:46:44', NULL, '92282e57e514c08df603650c82fc5ad1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'review', 'done', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '2352d517e219af8edf4537f4145b5a9e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '37b7881534e16c2f369cdfb4a25ac511', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, '7e4e0f286bd3bf1687cbbd49fca9e1f4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-5', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:48', '2026-04-22 11:46:48', '2026-04-22 11:46:48', NULL, 'c6ccbb7da6b303b5fd6ef4f5273c7d07', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:46:52', '2026-04-22 11:46:52', '2026-04-22 11:46:52', NULL, '99d159170d35cb6225a0b9e6f8e5a4f5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '171dab623718a0cb2a4af914c84e0d30', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '206793ce446e6ba302f209cda04dcb78', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '2a311168aab1126eadcb2e23433ba317', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '3098b6064c8b96eb459c5ed947ca97c4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '366f83e624514e442d539f704a0abbb1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '36c5d3bbd5f027fdb114391abdf1dda6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '381444444f3e04024e2293f61c774d1d', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '46d32785bb5113ebcb050845e67ea280', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '5fde942d02640b9df4e75d1d745b2de5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '74dbfcfee3f60d46ba6e910ebb5fed1b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '7d19553f3714932803e565e8ac106220', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'in_progress', 'review', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, '9de91c0384a97d66eaa01e7f8164f389', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'c257d281cc9fc54be99fea49688ff720', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'cf47b1a47c543dabd8fe0c891c535285', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'status', 'review', 'done', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'd34d4be4170d93183c18754a60ea97e1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:47:11', '2026-04-22 11:47:11', '2026-04-22 11:47:11', NULL, 'db0af7f083e8985026799a9d3334347d', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '1a24e0b9fbc1472aacf17392a9241b99', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '7774f4c92e18371341b7c0332022d29a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '8589b12b48657f3513e801cd96dab11c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'backlog', 'ready', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, '92508b82168bd20d5a69c63a66271c34', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'ready', 'in_progress', NULL, '2026-04-22 11:52:59', '2026-04-22 11:52:59', '2026-04-22 11:52:59', NULL, 'dc2b5b3b5b348409f6d719f05130804b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '0dd7c9716ba7dab383c7890822ba9224', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '23c19fa354da9eb201212b23696da027', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '79e01d297b5cf559d37f2c0ee3661a51', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '88a0fb2513eebbd4627abd854eefb484', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, '9ad3112f08548b5896fd2252dda48be0', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'acba548461502b88a483649f181a65da', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'bd986c8233a7a251c0403c4df3ce8511', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'cfb6a1faab0ce219609f44055648cda1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'dabc0f13943decd855d39febfd2a18ae', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'status', 'ready', 'in_progress', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'e340923ef96f70f142a0bee868bb8e67', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'review', 'done', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'f179c71abcd89f7ed9fa781220d2018c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:48', '2026-04-22 12:03:48', '2026-04-22 12:03:48', NULL, 'fae80bffb40c02fdf07691ef18837b14', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'in_progress', 'review', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '1693e0a6448fb98bd03fe0c4c65371fb', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-6', 'status', 'review', 'done', NULL, '2026-04-22 12:03:54', '2026-04-22 12:03:54', '2026-04-22 12:03:54', NULL, '80d695ac3bfc5fe1f3615013dea3b06a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '33a14771999bc0062268447b4ffadc73', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '5a2f1c3d37090ad5791c6a0e8a7aa80a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'ready', 'in_progress', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, '7d84a743a1b9e1ce5c50172b89318153', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'backlog', 'ready', NULL, '2026-04-22 14:16:39', '2026-04-22 14:16:39', '2026-04-22 14:16:39', NULL, 'cad02006950fb6fa0d003553437d3bbe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '10f0a16fa4e4899c7817dd5c44cc3ffe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'in_progress', 'review', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '2d697a30a6193eacf2a3ddf1661e861c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '591bb27186744d023df34105884fa58f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'status', 'review', 'done', NULL, '2026-04-22 14:30:05', '2026-04-22 14:30:05', '2026-04-22 14:30:05', NULL, '817b9d8e92707eb588cb7f9eae7d424e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'status', 'backlog', 'cancelled', NULL, '2026-04-22 20:34:17', '2026-04-22 20:34:17', '2026-04-22 20:34:17', NULL, '5460d369f6cdef9c393a37e41481bcb5', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '313d4c9dd6444a4573cbe9584ed18f61', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '4630269c56784316b975ca56b10a2337', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, '5a8f7e0eda55bc0893c6597400a8d535', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:38:42', '2026-04-22 20:38:42', '2026-04-22 20:38:42', NULL, 'fac6b818dc68490a80ea32255f0ba404', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '0a7137f82fbb9307496b7e4133b15052', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '5aff1ed40d9a68a5b4d59aab0d24dd31', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, '931bcaabbd64af0612fbe6eb9a4470d6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:38:49', '2026-04-22 20:38:49', '2026-04-22 20:38:49', NULL, 'c2fca20d28b2a3a63a56eb2841a4bda9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-31', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '84e5b99f4fb99f8ae4d189ddaac2de74', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-34', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, '8c7ba0fd4c8acc6065a24b80ae28d526', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-30', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'd91c6440f66e683a87be5e61a366cca7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-33', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:38:51', '2026-04-22 20:38:51', '2026-04-22 20:38:51', NULL, 'f9253848d9a95ce1823c8ba78a511fc0', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'in_progress', 'done', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '389d5abb35b3b73ccb38ac8bec3b92c7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'backlog', 'ready', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, '7e714e95f89966a13e436d2fe38e7443', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'status', 'ready', 'in_progress', NULL, '2026-04-22 20:56:58', '2026-04-22 20:56:58', '2026-04-22 20:56:58', NULL, 'b1aa8ff1f9b24cdfc9e0bebf21d38b99', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '39b407be88dbb31f530c8074f6bcecc7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '59df9c23d722ccf1c1ac18baee76c785', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-32', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:02:29', '2026-04-22 21:02:29', '2026-04-22 21:02:29', NULL, '76b48a80abcba29b1047c794fd004234', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '297763c026010189ea0bd870f77a173e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '2cd947436be1c156eb77d233aeed5da2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '38826870354a1bf51bc2ff21f6da0ea3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '5105038efff2e3055213b1b1403b7610', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '67cc6c0934711b6a592e11e5edc6194c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'backlog', 'ready', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, '6e9e7d3ce9f74ed261912b1cb099dcad', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'a4e702776f3b553fb276782e539ebfc7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'in_progress', 'done', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'd294248ba8ea651e78aeb6fed0457eb4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'status', 'ready', 'in_progress', NULL, '2026-04-22 21:16:41', '2026-04-22 21:16:41', '2026-04-22 21:16:41', NULL, 'da8dc2002a03eaee7fcd5504abee6f60', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '08f09f3bb9f1a0001110716930824e62', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-29', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '10005b4803d743aa21be0223c8a85d5c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '11ac23b546d0e22206af4221062f5912', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-21', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '127404fe79dfb79d0297b85d78235c68', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-23', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '15fb6606af61e11b6960799721e7cdcc', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-38', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '19f6209ce4428172fb16941accb13566', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-27', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '212224b7dcc4b991119dc430ae179311', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-10', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '2fe8eed15b3ead999a69cdd08df5e14c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-15', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '3990623d651c604fec692edb70976d69', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '44d273b92ad4c93159706c1f17fcb6a7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-19', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '46935c5a6d8ef12cf1c2252bd8d30368', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-37', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '551ea05a8d0cc28c0ff7010a139e6fe1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-14', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '6748fca610fc8a8503d69846231616fe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-20', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '7843cfda82ec1c1622c1a201f82acaf1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-13', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '822790bbace926feb2372b8665080932', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-22', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, '9a1ae5742a1230e60279d9c72f8b0f75', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-42', 'parent_id', NULL, 'T-5', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a414bc8e4d32fa32483228a4e9c7be8c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-24', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a80caae1913b8e9a1d5dab980bf0b77b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-40', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'a895d51a2e6e8b448684933cf0224162', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'parent_id', NULL, 'T-3', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ad9a8a85686e33df17ae15631afa1213', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-9', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'aedb3c83402245f81cd10f04d15dcf8e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-16', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b6dbb8114cd77c206d3b8bdf054736b9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-26', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'b7b189fe87f61d42e1d0318d23aeb1fe', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-11', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'c80049d2c236f0d2512355183b766f0f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-25', 'parent_id', NULL, 'T-8', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ccdf7bec2a75f5829eab4fdd57171622', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-36', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'd13ed78c92d33e61e448c9e155adf870', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-41', 'parent_id', NULL, 'T-7', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'eb2a2ca41a57604b40556e81bf6480a9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-35', 'parent_id', NULL, 'T-4', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f0d27e423d40a998115e10ffd804f791', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-39', 'parent_id', NULL, 'T-6', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'f5c891c9a5f7d5e3f43ded0dc07eb704', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-12', 'parent_id', NULL, 'T-2', NULL, '2026-04-23 10:23:49', '2026-04-23 10:23:49', '2026-04-23 10:23:49', NULL, 'ff609c22f964618c84b7c36988e87ae7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, '6ae864936d48565e880f06e984e9d978', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:01:08', '2026-04-24 07:01:08', '2026-04-24 07:01:08', NULL, 'ebebc38301a28001a09c9e7066c9aeb9', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '3cf128b79fe91447f72f42d8cffce9e1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:01:48', '2026-04-24 07:01:48', '2026-04-24 07:01:48', NULL, '68f57f5e3a1005ca3009f944b8b634d7', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:40', '2026-04-24 07:05:40', '2026-04-24 07:05:40', NULL, '50aa3e362dbe9682d98f6d5f71ea97b1', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:05:50', '2026-04-24 07:05:50', '2026-04-24 07:05:50', NULL, '4cb951c3ea697881d8fa5b0e86cfdf96', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:05:51', '2026-04-24 07:05:51', '2026-04-24 07:05:51', NULL, '7516ffa5c72fa4e7fd067249393c3653', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:06:30', '2026-04-24 07:06:30', '2026-04-24 07:06:30', NULL, '268576bd9559485dd2ac5e7ffd1f1a79', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:06:32', '2026-04-24 07:06:32', '2026-04-24 07:06:32', NULL, 'ef46c3a3db4c4ba50ff1f0e1baa4c0e6', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'review', 'done', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '1cd74d47eb547aa0bef71597eaaa2c5b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '3b8c17d366d1710d03523303c9df83c8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'review', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, '7eb9ca56292802301f93d0e2d680835e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:07:55', '2026-04-24 07:07:55', '2026-04-24 07:07:55', NULL, 'a1a837494c047ade786d79edb75296dd', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:00', '2026-04-24 07:08:00', '2026-04-24 07:08:00', NULL, 'ac745b5254a0e8f085189c23d95acb7e', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'done', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, '2adaf942a49bfeeac90aee1527a98444', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'done', 'in_progress', NULL, '2026-04-24 07:08:29', '2026-04-24 07:08:29', '2026-04-24 07:08:29', NULL, 'e0d54ffba34677dc6e687be801ccec05', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, '74e6fa2f524c21300467381c2f3ad4e3', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-17', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:35', '2026-04-24 07:08:35', '2026-04-24 07:08:35', NULL, 'fbd19eabf442e6e0de60028c28956b8f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '7d3efe4ccaee7d45d1a01d28144c4f0a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'ready', 'in_progress', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, '914a2f5f5ef0807a6743f8811e71804b', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'in_progress', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'a1cd74c76fd10c353aa758cea0331c5c', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'cancelled', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'cdbe85f80838e781048780db934d0115', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'cancelled', 'backlog', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f24e8d138172597d7ddcf26672b67d5f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'ready', NULL, '2026-04-24 07:08:59', '2026-04-24 07:08:59', '2026-04-24 07:08:59', NULL, 'f9a83fa1b41d56202c57e6a55b240f35', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'backlog', 'done', NULL, '2026-04-24 07:30:15', '2026-04-24 07:30:15', '2026-04-24 07:30:15', NULL, '99c4e5a68463201e7f1b7764eddfd2ae', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-18', 'status', 'done', 'backlog', NULL, '2026-04-24 07:30:22', '2026-04-24 07:30:22', '2026-04-24 07:30:22', NULL, 'd0274058b130d8003123881b8a410f7f', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, '83d70eb5a7f6e7175e0719fdb23243c2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:08:16', '2026-04-24 08:08:16', '2026-04-24 08:08:16', NULL, 'b5acf95cb059f0c573b78d755b938da2', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:23', '2026-04-24 08:08:23', '2026-04-24 08:08:23', NULL, '4ae08b8af459af0679b05cf1f8ac3950', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:08:38', '2026-04-24 08:08:38', '2026-04-24 08:08:38', NULL, 'c7e4cabf5d1fccad28f22d498e91193a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:08:40', '2026-04-24 08:08:40', '2026-04-24 08:08:40', NULL, '9b0937bc7eb82785407c367a90365c3a', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'review', NULL, '2026-04-24 08:08:44', '2026-04-24 08:08:44', '2026-04-24 08:08:44', NULL, '90587f61d96b12ce53f2a4edc705fdd8', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'review', 'in_progress', NULL, '2026-04-24 08:08:48', '2026-04-24 08:08:48', '2026-04-24 08:08:48', NULL, 'd02ac7ee61fc4dc420fb7597a4f326db', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'in_progress', 'ready', NULL, '2026-04-24 08:16:15', '2026-04-24 08:16:15', '2026-04-24 08:16:15', NULL, '145613c94b4366bda03fb76c0f0747ce', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'backlog', NULL, '2026-04-24 08:16:19', '2026-04-24 08:16:19', '2026-04-24 08:16:19', NULL, '0d8e318e8060aece6e18788cee56f646', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:16:21', '2026-04-24 08:16:21', '2026-04-24 08:16:21', NULL, '3d8635cfdbaf9b0c22dcba9f15f3c1ad', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-63', 'status', 'ready', 'in_progress', NULL, '2026-04-24 08:16:47', '2026-04-24 08:16:47', '2026-04-24 08:16:47', NULL, '77f873a7a5fff47ce9b974a6999d03b4', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-28', 'status', 'backlog', 'in_progress', NULL, '2026-04-24 08:16:56', '2026-04-24 08:16:56', '2026-04-24 08:16:56', NULL, 'e7610d68ec9871746b4a361e33b18f05', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-43', 'status', 'backlog', 'ready', NULL, '2026-04-24 08:17:11', '2026-04-24 08:17:11', '2026-04-24 08:17:11', NULL, '9c3afbbfca207aeb78541dbd9d90e462', 1) ON CONFLICT(hash) DO NOTHING;
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,111 @@
|
|||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'description', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.', NULL, '2026-07-02 06:35:03', '2026-07-02 06:35:03.555', '2026-07-02 06:35:03.555', NULL, '33a6fd1c81f2e1142d15ce5791ce3b24', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'description', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).', NULL, '2026-07-02 08:33:27', '2026-07-02 08:33:27.519', '2026-07-02 08:33:27.519', NULL, '65090e3a71c9f5f49b8070a112216210', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D0GAXM1FN42PJKG7FE34G', 'status', 'backlog', 'done', NULL, '2026-07-02 09:55:52', '2026-07-02 09:55:52.114', '2026-07-02 09:55:52.114', NULL, 'a417eec1fa067a31e46b21578a6228fb', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'description', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).
|
||||||
|
|
||||||
|
COMPLETE (2026-07-02, session 2). All scope delivered + tested (56 graph tests, make test green, real-boot verified via testmode). Slices this session: GraphController (3b67725b), pane shell (6fae1bc4), extension+i18n registration (a5acb6ac), pan+zoom (e6556401), testmode coverage (46d9b403), filter model (f859173b), filter bar (aabec87d). Final feature: force-directed vault graph in the context panel (graph.view, D-47) — hover-highlight, click-to-open, scroll-zoom, drag-pan, and filters (path glob re-queries pql; depth-from-active local graph; tri-state tag include/exclude). Controller uses pql.meta (outlinks+tags in one call) and strips #heading fragments so heading links connect. NOTE: pql data load is 1 files + N meta calls (sequential); batching is a future optimisation if large vaults feel slow.', NULL, '2026-07-02 19:47:37', '2026-07-02 19:47:37.694', '2026-07-02 19:47:37.694', NULL, 'a9f6b8b38858b687f106d1bda236821d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'status', 'in_progress', 'done', NULL, '2026-07-02 19:47:44', '2026-07-02 19:47:44.357', '2026-07-02 19:47:44.357', NULL, 'c8bf520d62290050e6d0feb4a9a6a68d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'description', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.', NULL, '2026-07-02 20:27:03', '2026-07-02 20:27:03.493', '2026-07-02 20:27:03.493', NULL, '7a661d8cc999f526e26cb1a14b7839c4', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'description', NULL, 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.', NULL, '2026-07-02 20:31:02', '2026-07-02 20:31:02.807', '2026-07-02 20:31:02.807', NULL, '5030849d297f6312073802a0641a2594', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'status', 'backlog', 'in_progress', NULL, '2026-07-02 20:35:12', '2026-07-02 20:35:12.739', '2026-07-02 20:35:12.739', NULL, 'd971e23e05c7547672b6989ca0a98434', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'description', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.
|
||||||
|
|
||||||
|
EVIDENCE + ROOT CAUSE (2026-07-02, from a /model screenshot). The confirmation renders as a raw, unstyled line: literally ''<local-command-stdout>Set model to claude-fable-5[1m] (claude-fable-5)</local-command-stdout>'', shown under the ''you'' (user) speaker stripe. Three distinct defects in that one line: (a) the CLI''s <local-command-stdout> wrapper tag is displayed verbatim instead of being unwrapped; (b) an ANSI SGR bold code leaks through as literal ''[1m]'' (a \x1b[1m) — slash-command stdout is not ANSI-stripped; (c) it is attributed to the USER speaker, so a system/command acknowledgement masquerades as something the user typed. ROOT CAUSE: clide has NO handling for local-command-stdout at all (grep in lib/ = zero hits) — the slash-command result falls through and is rendered as plain user prose. ENTRY POINTS for the fix: inbound message parse / role attribution in lib/builtin/claude/src/transcript_reader.dart; existing ANSI-strip refs in transcript_reader.dart + claude_composer.dart. IMPROVE: detect local-command-stdout content, unwrap the tag + strip ANSI, and render it as a distinct, clearly-positioned system/command-acknowledgement (NOT the user stripe) so a /model or /effort change is an unmistakable confirmation. Affects all slash-command stdout (model, effort, etc.), so fix at the render/parse path, not per-command.', NULL, '2026-07-02 20:39:06', '2026-07-02 20:39:06.684', '2026-07-02 20:39:06.684', NULL, '02ea6e2dbb60929aed687275f5329a4f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'description', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.
|
||||||
|
|
||||||
|
EVIDENCE + ROOT CAUSE (2026-07-02, from a /model screenshot). The confirmation renders as a raw, unstyled line: literally ''<local-command-stdout>Set model to claude-fable-5[1m] (claude-fable-5)</local-command-stdout>'', shown under the ''you'' (user) speaker stripe. Three distinct defects in that one line: (a) the CLI''s <local-command-stdout> wrapper tag is displayed verbatim instead of being unwrapped; (b) an ANSI SGR bold code leaks through as literal ''[1m]'' (a \x1b[1m) — slash-command stdout is not ANSI-stripped; (c) it is attributed to the USER speaker, so a system/command acknowledgement masquerades as something the user typed. ROOT CAUSE: clide has NO handling for local-command-stdout at all (grep in lib/ = zero hits) — the slash-command result falls through and is rendered as plain user prose. ENTRY POINTS for the fix: inbound message parse / role attribution in lib/builtin/claude/src/transcript_reader.dart; existing ANSI-strip refs in transcript_reader.dart + claude_composer.dart. IMPROVE: detect local-command-stdout content, unwrap the tag + strip ANSI, and render it as a distinct, clearly-positioned system/command-acknowledgement (NOT the user stripe) so a /model or /effort change is an unmistakable confirmation. Affects all slash-command stdout (model, effort, etc.), so fix at the render/parse path, not per-command.', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.
|
||||||
|
|
||||||
|
EVIDENCE + ROOT CAUSE (2026-07-02, from a /model screenshot). The confirmation renders as a raw, unstyled line: literally ''<local-command-stdout>Set model to claude-fable-5[1m] (claude-fable-5)</local-command-stdout>'', shown under the ''you'' (user) speaker stripe. Three distinct defects in that one line: (a) the CLI''s <local-command-stdout> wrapper tag is displayed verbatim instead of being unwrapped; (b) an ANSI SGR bold code leaks through as literal ''[1m]'' (a \x1b[1m) — slash-command stdout is not ANSI-stripped; (c) it is attributed to the USER speaker, so a system/command acknowledgement masquerades as something the user typed. ROOT CAUSE: clide has NO handling for local-command-stdout at all (grep in lib/ = zero hits) — the slash-command result falls through and is rendered as plain user prose. ENTRY POINTS for the fix: inbound message parse / role attribution in lib/builtin/claude/src/transcript_reader.dart; existing ANSI-strip refs in transcript_reader.dart + claude_composer.dart. IMPROVE: detect local-command-stdout content, unwrap the tag + strip ANSI, and render it as a distinct, clearly-positioned system/command-acknowledgement (NOT the user stripe) so a /model or /effort change is an unmistakable confirmation. Affects all slash-command stdout (model, effort, etc.), so fix at the render/parse path, not per-command.
|
||||||
|
|
||||||
|
SCOPE (do not narrow): the local-command-stdout rendering defect above is ONE symptom, not the whole ticket. The core problem is that after switching model or effort the user has no reliable, well-placed signal that it took effect — so this stays a broad investigate-and-improve of the switch/toggle trust UX, with the render bug as just the first concrete instance. Other symptoms/questions to investigate (non-exhaustive): does the control itself (Config tab picker / effort control / any menu) visibly update to the NEW active value after a switch, or does it look unchanged? is there ANY acknowledgement at the point of interaction, or only (mangled) output buried in the transcript far from where the user clicked? do model vs effort behave consistently, or differently? can clide''s shown ''active'' value drift from what actually took effect (e.g. a switch that silently no-ops)? is the confirmation positioned where the eye already is? The deliverable is: across all these controls, a consistent and unmistakable ''this is now active'' — fixing the render path is necessary but not sufficient. Enumerate the full symptom set during investigation before designing the fix.', NULL, '2026-07-02 20:41:13', '2026-07-02 20:41:13.402', '2026-07-02 20:41:13.402', NULL, '1c7d99c842cc857d5978d91e5b23ab8b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'description', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).', NULL, '2026-07-02 21:22:59', '2026-07-02 21:22:59.395', '2026-07-02 21:22:59.395', NULL, '6b17245b0d3d39a0d61bc90a2a0a034b', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'description', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).
|
||||||
|
|
||||||
|
Refinement (2026-07-03, user-confirmed): (1) SLOT: Slots.workspace — diff/editor recipe, center column; coexists with Claude the way diff does (D-47). (2) TABS: real MultitabPane<CanvasDoc> — N .canvas files open as tabs (user explicitly chose over the single-TabContribution graph/diff precedent; needs MultitabController plumbing like Claude sessions). (3) FILE-OPEN ROUTING resolved by inspection: TabContribution.fileGlobs is dead (zero consumers) — do NOT wire it. Add a .canvas branch in lib/kernel/src/file_open.dart openWorkspaceFile() publishing to ''builtin.canvas''/''selection'' (mirror of the .md branch), and D-6 CLI parity via a ''canvas'' entry in the _readers map at lib/src/daemon/ui_command.dart:34 → clide ui open canvas <path> (diff precedent). (4) Fix stale doc header lib/src/canvas/json_canvas.dart:5-7 (claims SVG-lowering; actual architecture paints CanvasDoc directly per the ticket''s DECISION NOTE) in the same pass. (5) Edit phase later needs a mutation path (CanvasView has no onChanged; CanvasDoc is immutable-construction only) — deferred, flagged now.', NULL, '2026-07-03 20:20:00', '2026-07-03 20:20:00.827', '2026-07-03 20:20:00.827', NULL, '541312e6b1f559f60934ad1a1b784d76', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'description', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).
|
||||||
|
|
||||||
|
Refinement (2026-07-03, user-confirmed): (1) SLOT: Slots.workspace — diff/editor recipe, center column; coexists with Claude the way diff does (D-47). (2) TABS: real MultitabPane<CanvasDoc> — N .canvas files open as tabs (user explicitly chose over the single-TabContribution graph/diff precedent; needs MultitabController plumbing like Claude sessions). (3) FILE-OPEN ROUTING resolved by inspection: TabContribution.fileGlobs is dead (zero consumers) — do NOT wire it. Add a .canvas branch in lib/kernel/src/file_open.dart openWorkspaceFile() publishing to ''builtin.canvas''/''selection'' (mirror of the .md branch), and D-6 CLI parity via a ''canvas'' entry in the _readers map at lib/src/daemon/ui_command.dart:34 → clide ui open canvas <path> (diff precedent). (4) Fix stale doc header lib/src/canvas/json_canvas.dart:5-7 (claims SVG-lowering; actual architecture paints CanvasDoc directly per the ticket''s DECISION NOTE) in the same pass. (5) Edit phase later needs a mutation path (CanvasView has no onChanged; CanvasDoc is immutable-construction only) — deferred, flagged now.', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).
|
||||||
|
|
||||||
|
Refinement (2026-07-03, user-confirmed): (1) SLOT: Slots.workspace — diff/editor recipe, center column; coexists with Claude the way diff does (D-47). (2) TABS: real MultitabPane<CanvasDoc> — N .canvas files open as tabs (user explicitly chose over the single-TabContribution graph/diff precedent; needs MultitabController plumbing like Claude sessions). (3) FILE-OPEN ROUTING resolved by inspection: TabContribution.fileGlobs is dead (zero consumers) — do NOT wire it. Add a .canvas branch in lib/kernel/src/file_open.dart openWorkspaceFile() publishing to ''builtin.canvas''/''selection'' (mirror of the .md branch), and D-6 CLI parity via a ''canvas'' entry in the _readers map at lib/src/daemon/ui_command.dart:34 → clide ui open canvas <path> (diff precedent). (4) Fix stale doc header lib/src/canvas/json_canvas.dart:5-7 (claims SVG-lowering; actual architecture paints CanvasDoc directly per the ticket''s DECISION NOTE) in the same pass. (5) Edit phase later needs a mutation path (CanvasView has no onChanged; CanvasDoc is immutable-construction only) — deferred, flagged now.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-05): REACHABLE-INTEGRATION PHASE COMPLETE (e2e305de). CanvasExtension is a real workspace pane: app-scoped MultitabController on the extension (diff/T-233 pattern) with real per-document sub-tabs (MultitabPane keepAlive, per refinement decision), CanvasPaneHost + CanvasDocumentTab (files.read -> CanvasDoc.parse -> CanvasView; loading/error states), routing wired (openWorkspaceFile .canvas branch; ui.open ''canvas'' reader so clide ui open canvas <path> works; fileGlobs left dead as decided), en_us+nl_nl catalogs, json_canvas doc header corrected. Tests: extension lifecycle (7), pane-host widget (6), file_open routing (5, new file), ui_command canvas case; testmode extension roster now includes builtin.canvas (26/26 real-boot pass). REMAINING (edit phase, fresh session): node drag + resize, add note/text/edge affordances, persist CanvasDoc back to disk — encode() exists; CanvasView needs an onChanged/mutation path (refinement note item 5).', NULL, '2026-07-05 07:29:15', '2026-07-05 07:29:15.452', '2026-07-05 07:29:15.452', NULL, '0d0ff6c05b550d4a85296eb38adc830f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'status', 'backlog', 'in_progress', NULL, '2026-07-05 09:52:54', '2026-07-05 09:52:54.013', '2026-07-05 09:52:54.013', NULL, '59efe4bd0a098bfea3f146af21b0caf3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'status', 'in_progress', 'done', NULL, '2026-07-05 10:54:23', '2026-07-05 10:54:23.532', '2026-07-05 10:54:23.532', NULL, '941d08bde0cc4479860e015aded3d664', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'status', 'backlog', 'in_progress', NULL, '2026-07-13 15:17:17', '2026-07-13 15:17:17.537', '2026-07-13 15:17:17.537', NULL, 'fb951233b5fc242889cae1156dc1d0d8', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'description', NULL, 'Implements D-106 (FR-1 + worktree addendum). Storage: user-scope key app.env.pathPrepend.<fnv1a64Hex(canonicalWorkspaceKey(presetRoot))> in ~/.config/clide/settings.yaml — never committed; presetRootFor() resolves a linked-worktree workspace (gitdir: pointer file, e.g. .worktrees/<name>) to the main repo root so all worktrees share the repo''s preset.
|
||||||
|
|
||||||
|
Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pathForSpawn hook (main.dart wires the preset-aware closure); hosted Claude via agentEnvDelta(prependDirs:) — now exports PATH whenever a preset exists even if clide is already on PATH (previous gap) — threaded orchestrator.pathPresetFor ← claude extension ← ctx.settings. Toolchain/supporter-binary resolution deliberately preset-blind (T-98/D-92 fence).
|
||||||
|
|
||||||
|
CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs.
|
||||||
|
|
||||||
|
.worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', NULL, '2026-07-13 15:39:31', '2026-07-13 15:39:31.309', '2026-07-13 15:39:31.309', NULL, '44007d87d28b52050716cd913009d341', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'status', 'in_progress', 'done', NULL, '2026-07-13 16:48:56', '2026-07-13 16:48:56.833', '2026-07-13 16:48:56.833', NULL, 'd6c02324e60b8d412840b1ffd600a13f', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTF7KE5Y497PQC7SCFGR1KC', 'status', 'backlog', 'done', NULL, '2026-07-13 20:49:17', '2026-07-13 20:49:17.282', '2026-07-13 20:49:17.282', NULL, 'd2d3b437c1063f835e5b34c0cd996f9d', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
@@ -0,0 +1,364 @@
|
|||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0ABC7QNEC3XCTV73YPSGR4', 'description', 'User report 2026-06-16: Claude Code''s **remote-control** feature (start / monitor / steer a running Claude Code session remotely — e.g. from claude.ai or the mobile app) is **not plumbed into clide**.
|
||||||
|
|
||||||
|
clide hosts the `claude` CLI as a stream-json child (`--session-id` / `--resume`, D-77). For remote control to work through clide, a clide-hosted session needs to be discoverable + steerable by the remote-control surface the same way a terminal-launched `claude` is.
|
||||||
|
|
||||||
|
**Step 1 — characterize (don''t assume the mechanism):** determine exactly what Claude Code exposes for remote control on the running CLI version. Likely touch points:
|
||||||
|
- the `~/.claude/sessions/<pid>.json` live-session registry we characterized in T-437 (PID-keyed: sessionId, cwd, version, kind, entrypoint, status) — is this what the remote-control surface enumerates? clide-spawned sessions DO write an entry (we saw `entrypoint: sdk-cli`). Confirm whether clide''s entry is visible/controllable remotely, or whether `entrypoint: sdk-cli` / headless spawn excludes it.
|
||||||
|
- any flag / capability in the `initialize` stream-json probe (T-411/T-151 cache) advertising remote control.
|
||||||
|
- whether enrollment requires the interactive TUI (and so is suppressed under clide''s stream-json spawn).
|
||||||
|
|
||||||
|
**Step 2 — plumb:** wire clide so a clide-hosted session participates in remote control (register correctly / pass the needed flag), and surface its state in the UI (e.g. an indicator that the session is remote-controllable / being driven remotely). If it conflicts with clide''s session ownership (pane pins a session-id, T-156), document the boundary.
|
||||||
|
|
||||||
|
**Open question:** is the goal (a) clide sessions become remotely controllable from claude.ai/mobile, or (b) clide can act as a remote controller of other sessions? Default read is (a). Confirm with the user before building.
|
||||||
|
|
||||||
|
Related: D-77 (stream-json session model), T-437 (sessions registry characterization), T-156 (clide owns session lifecycle), T-411 (capability probe).', 'User report 2026-06-16: Claude Code''s **remote-control** feature (start / monitor / steer a running Claude Code session remotely — e.g. from claude.ai or the mobile app) is **not plumbed into clide**.
|
||||||
|
|
||||||
|
clide hosts the `claude` CLI as a stream-json child (`--session-id` / `--resume`, D-77). For remote control to work through clide, a clide-hosted session needs to be discoverable + steerable by the remote-control surface the same way a terminal-launched `claude` is.
|
||||||
|
|
||||||
|
**Step 1 — characterize (don''t assume the mechanism):** determine exactly what Claude Code exposes for remote control on the running CLI version. Likely touch points:
|
||||||
|
- the `~/.claude/sessions/<pid>.json` live-session registry we characterized in T-437 (PID-keyed: sessionId, cwd, version, kind, entrypoint, status) — is this what the remote-control surface enumerates? clide-spawned sessions DO write an entry (we saw `entrypoint: sdk-cli`). Confirm whether clide''s entry is visible/controllable remotely, or whether `entrypoint: sdk-cli` / headless spawn excludes it.
|
||||||
|
- any flag / capability in the `initialize` stream-json probe (T-411/T-151 cache) advertising remote control.
|
||||||
|
- whether enrollment requires the interactive TUI (and so is suppressed under clide''s stream-json spawn).
|
||||||
|
|
||||||
|
**Step 2 — plumb:** wire clide so a clide-hosted session participates in remote control (register correctly / pass the needed flag), and surface its state in the UI (e.g. an indicator that the session is remote-controllable / being driven remotely). If it conflicts with clide''s session ownership (pane pins a session-id, T-156), document the boundary.
|
||||||
|
|
||||||
|
**Open question:** is the goal (a) clide sessions become remotely controllable from claude.ai/mobile, or (b) clide can act as a remote controller of other sessions? Default read is (a). Confirm with the user before building.
|
||||||
|
|
||||||
|
Related: D-77 (stream-json session model), T-437 (sessions registry characterization), T-156 (clide owns session lifecycle), T-411 (capability probe).
|
||||||
|
|
||||||
|
## Step 1 COMPLETE — mechanism characterized and empirically proven (2026-08-07)
|
||||||
|
|
||||||
|
**Goal confirmed as (a):** clide-hosted sessions become remotely controllable from
|
||||||
|
claude.ai / the mobile app. (b) is not in scope.
|
||||||
|
|
||||||
|
### The mechanism is a control_request, not the sessions registry
|
||||||
|
|
||||||
|
The Step-1 hypothesis (that `~/.claude/sessions/<pid>.json` is what the remote
|
||||||
|
surface enumerates) is **wrong**. That registry is incidental. Remote Control is
|
||||||
|
enabled per-session over the stream-json control channel clide already owns.
|
||||||
|
|
||||||
|
Claude Code 2.1.220 ships two bridge integrations:
|
||||||
|
- `[bridge:repl]` — the interactive TUI path (`--remote-control` flag, `/remote-control`)
|
||||||
|
- `[bridge:sdk]` — a **stream-json/SDK path**, which is the one clide needs
|
||||||
|
|
||||||
|
No interactive session, no extra flag, and no CLI changes are required.
|
||||||
|
|
||||||
|
### Wire contract (verified live)
|
||||||
|
|
||||||
|
```
|
||||||
|
→ {"type":"control_request","request_id":"…",
|
||||||
|
"request":{"subtype":"remote_control","enabled":true,"name":"<session name>"}}
|
||||||
|
|
||||||
|
← {"type":"system","subtype":"bridge_state","state":"ready"}
|
||||||
|
← {"type":"control_response","response":{"subtype":"success","response":{
|
||||||
|
"session_url":"https://claude.ai/code/session_0127…",
|
||||||
|
"connect_url":"https://claude.ai/code?environment=",
|
||||||
|
"environment_id":""}}}
|
||||||
|
← {"type":"system","subtype":"bridge_state","state":"connected"}
|
||||||
|
|
||||||
|
→ {"request":{"subtype":"remote_control","enabled":false}} # clean teardown
|
||||||
|
← {"type":"control_response","response":{"subtype":"success"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Proven by probe against clide''s exact spawn flags (`stream_json_session.dart:78`).
|
||||||
|
`ready → connected` in ~420ms. Debug log confirms `[bridge:sdk] State change: ready`
|
||||||
|
then `connected`; transport is CCR v2 over SSE, shared with the repl bridge.
|
||||||
|
|
||||||
|
**Surface `session_url`, not `connect_url`.** `connect_url` came back as
|
||||||
|
`https://claude.ai/code?environment=` with an empty `environment_id` — the
|
||||||
|
environment concept is not populated on the bare-SDK path (it appears to be filled
|
||||||
|
in only when the `claude remote-control` daemon owns a registered directory).
|
||||||
|
`session_url` is the complete, live link. Confirm before building a QR affordance.
|
||||||
|
|
||||||
|
### CLI-side callback surface (from binary analysis)
|
||||||
|
|
||||||
|
| Callback | Effect |
|
||||||
|
|---|---|
|
||||||
|
| `onInboundMessage` | remote message injected as a user turn (tagged `bridgeOrigin`, `clientPlatform`, `origin`) |
|
||||||
|
| `onPermissionResponse` | → `injectControlResponse` — the remote can answer permission prompts |
|
||||||
|
| `onInterrupt` | remote cancel of the running turn |
|
||||||
|
| `onSetModel` / `onSetPermissionMode` / `onSetMaxThinkingTokens` | remote session control |
|
||||||
|
| `onStateChange` | emits `system/bridge_state` (`ready`\|`connected`\|`failed` + `detail`) on the normal output stream |
|
||||||
|
|
||||||
|
Plus outbound `writeSdkMessages` forwarding of task/thinking/vcs events.
|
||||||
|
|
||||||
|
### Prompt arbitration — resolved, no clide policy to invent
|
||||||
|
|
||||||
|
Decided model (user, 2026-08-07): **first-to-apply wins, both sides linked by the
|
||||||
|
same `request_id`, loser''s prompt retracts on that link, clear is idempotent.**
|
||||||
|
|
||||||
|
This is already the shipped protocol, and it is symmetric:
|
||||||
|
- `setOnControlRequestSent` forwards the pending request to the remote;
|
||||||
|
`setOnControlRequestResolved` → `sendControlCancelRequest(request_id)` retracts it.
|
||||||
|
- `RemoteSessionManager.handleMessage` handles inbound `control_cancel_request` by
|
||||||
|
looking up `pendingPermissionRequests` / `pendingDialogRequests` and retracting;
|
||||||
|
unknown ids are ignored ("nothing pending, ignoring").
|
||||||
|
- The refusal schema states the rule directly: *"Evict on RESOLUTION (your own
|
||||||
|
response — any choice — or `control_cancel_request` retirement), never on receipt
|
||||||
|
… Eviction is idempotent."*
|
||||||
|
|
||||||
|
**The clide gap:** `stream_json_session.dart` parses `control_request` but has **no
|
||||||
|
`control_cancel_request` handling at all**. If the remote answers first, clide''s
|
||||||
|
prompt widget hangs with no retraction. Since pending prompts are already keyed by
|
||||||
|
`request_id` for `resolvePrompt()` (`:758`), the fix is a delete + UI clear on the
|
||||||
|
same key. NOT YET OBSERVED live — the probe ran no tools, so the retraction path is
|
||||||
|
confirmed by decompile only. Verify during implementation.
|
||||||
|
|
||||||
|
### Step 2 scope (remaining)
|
||||||
|
|
||||||
|
1. `enableRemoteControl({String? name})` / `disableRemoteControl()` on
|
||||||
|
`StreamJsonSession` — shaped exactly like `setModel()` (`:932`): request with
|
||||||
|
`request_id`, pending map, reconcile response into `SessionStatus`.
|
||||||
|
2. Handle `system/bridge_state` in the event switch → connection state.
|
||||||
|
3. **Handle inbound `control_cancel_request` → retract the matching pending
|
||||||
|
`ToolPrompt`.** (The arbitration work above; also correct on its own merits.)
|
||||||
|
4. Two `SessionStatus` fields (`session_url`, bridge state).
|
||||||
|
5. Cockpit affordance: connect link / QR + connected indicator.
|
||||||
|
6. `clide claude remote-control <on|off>` verb for D-6 parity.
|
||||||
|
7. Teardown on pane close; pass clide''s derived pane name as `name` (the CLI
|
||||||
|
already names clide sessions e.g. `clide-18`).
|
||||||
|
|
||||||
|
### Constraints found
|
||||||
|
|
||||||
|
- Requires a logged-in subscription account; bridge is skipped on non-first-party
|
||||||
|
providers (`isFirstPartyProvider` check) — needs a disabled UI state.
|
||||||
|
- Help text for the daemon path notes the workspace trust dialog must have been
|
||||||
|
accepted by running `claude` interactively in the directory once. clide spawns
|
||||||
|
non-interactively where trust is auto-skipped — verify this doesn''t block the bridge.
|
||||||
|
- `remoteControlAtStartup` is a user setting ("Start Remote Control bridge
|
||||||
|
automatically each session") — a zero-code way to A/B the behaviour, and a
|
||||||
|
setting clide should probably respect rather than fight.
|
||||||
|
- Related but out of scope: `isolatePeerMachines` (cross-machine `SendMessage`
|
||||||
|
between peer sessions); `claude remote-control` hidden subcommand (`bridgeMain`)
|
||||||
|
which runs a per-directory daemon with `--spawn same-dir|worktree|session`.', NULL, '2026-08-07 12:21:08', '2026-08-07 12:21:08.809', '2026-08-07 12:21:08.809', NULL, '3908441f5df127b533670e4b4e35b283', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'description', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.', NULL, '2026-08-07 12:30:44', '2026-08-07 12:30:44.880', '2026-08-07 12:30:44.880', NULL, 'aaccee60badf01e93df53301dd52dc79', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'priority', 'medium', 'high', NULL, '2026-08-07 12:30:59', '2026-08-07 12:30:59.962', '2026-08-07 12:30:59.962', NULL, '98d21d1e300343931ea7601b217a3b8e', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'title', 'pre-commit changelog hook leaves ticket_deps/ticket_idmap unstaged', 'pre-commit hook stages no .pql/changelog files (pql plan export --stage)', NULL, '2026-08-07 12:30:59', '2026-08-07 12:30:59.967', '2026-08-07 12:30:59.967', NULL, '4f3d1bf15c90af6ba608067a90d78e77', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
|
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'description', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.
|
||||||
|
|
||||||
|
### Correction (same session): not an untracked-file issue — `--stage` never stages
|
||||||
|
|
||||||
|
The "new-month rollover / untracked path" contributing factor above is **disproved**.
|
||||||
|
Tested directly: with `tickets/2026-08.sql` and `ticket_history/2026-08.sql` already
|
||||||
|
tracked and merely *modified*, a bare `git commit` still aborted with "no changes
|
||||||
|
added to commit". Hook output was identical:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tracked-modified and untracked-new both fail. The only common factor is
|
||||||
|
`rows_written: 0`.
|
||||||
|
|
||||||
|
**Escalates the diagnosis:** this is not intermittent and not table-specific.
|
||||||
|
Because ticket mutations write through to `.pql/changelog/` synchronously, the
|
||||||
|
pre-commit export always finds zero rows left to append, so `--stage` skips its
|
||||||
|
`git add` on *every* commit. In this repo the hook''s staging step is effectively
|
||||||
|
dead — it has likely never worked, and every ticket change that landed did so
|
||||||
|
because some other file in the commit was staged by hand, or because someone
|
||||||
|
noticed and re-added.
|
||||||
|
|
||||||
|
That reframes the earlier `ticket_deps` / `ticket_idmap` reports: those tables
|
||||||
|
weren''t being singled out, they were just the cases where nothing else in the
|
||||||
|
commit masked the failure.
|
||||||
|
|
||||||
|
**Fix (pql):** `plan export --stage` must stage on file state, not on
|
||||||
|
`rows_written` — `git add` every dirty-or-untracked path under `.pql/changelog/`
|
||||||
|
whenever the directory differs from the index, including when the export was a
|
||||||
|
no-op. Consider also dropping the hook''s `2>/dev/null || true` so a staging
|
||||||
|
failure is visible instead of silent.', NULL, '2026-08-07 12:31:41', '2026-08-07 12:31:41.109', '2026-08-07 12:31:41.109', NULL, '52366e812f9b77586b07f322791e4fd3', 2) ON CONFLICT(hash) DO NOTHING;
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
-- Auto-generated by migrate-ids (D-26). CREATE TABLE statements
|
||||||
|
-- for the planning schema; per-table dir keeps the changelog
|
||||||
|
-- self-describing per D-15.
|
||||||
|
-- pql:created_by: migrate-ids
|
||||||
|
-- pql:canonical_version: 2
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS decisions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
type TEXT NOT NULL CHECK(type IN ('confirmed','question','rejected')),
|
||||||
|
domain TEXT NOT NULL,
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
status TEXT NOT NULL DEFAULT 'active'
|
||||||
|
CHECK(status IN ('active','superseded','resolved','open')),
|
||||||
|
date TEXT,
|
||||||
|
file_path TEXT NOT NULL,
|
||||||
|
synced_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS decision_refs (
|
||||||
|
source_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
|
||||||
|
target_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
|
||||||
|
ref_type TEXT NOT NULL
|
||||||
|
CHECK(ref_type IN ('supersedes','references','resolves','depends_on','amends')),
|
||||||
|
note TEXT,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER,
|
||||||
|
PRIMARY KEY (source_id, target_id, ref_type)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Identity split (D-26): a ticket's stable, collision-proof identity is its
|
||||||
|
-- record_id (a locally-generated ULID, planning.NewRecordID); the friendly
|
||||||
|
-- T-NNN label lives in ticket_idmap and may be reconciled. Every structural
|
||||||
|
-- reference (parent, deps, history, labels) targets record_id, so a label
|
||||||
|
-- clash never corrupts the graph — only ticket_idmap needs a relabel.
|
||||||
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
|
record_id TEXT PRIMARY KEY,
|
||||||
|
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
||||||
|
parent_record_id TEXT REFERENCES tickets(record_id),
|
||||||
|
title TEXT NOT NULL,
|
||||||
|
description TEXT,
|
||||||
|
-- No CHECK enumeration: the ticket status vocabulary is per-vault
|
||||||
|
-- configurable (ticket_statuses in .pql/config.yaml). Validation lives
|
||||||
|
-- in Go (planning.StatusSet), so adding/renaming statuses needs no
|
||||||
|
-- schema change. The DEFAULT is a harmless fallback — CreateTicket
|
||||||
|
-- always inserts the configured default explicitly.
|
||||||
|
status TEXT NOT NULL DEFAULT 'backlog',
|
||||||
|
priority TEXT DEFAULT 'medium'
|
||||||
|
CHECK(priority IN ('critical','high','medium','low')),
|
||||||
|
assigned_to TEXT,
|
||||||
|
team TEXT,
|
||||||
|
decision_ref TEXT REFERENCES decisions(id),
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
-- ticket_idmap maps a record_id to its current friendly label (T-NNN).
|
||||||
|
-- ticket_id is intentionally NOT globally unique: two uncoordinated clones
|
||||||
|
-- can mint the same label, which surfaces as a duplicate-label collision
|
||||||
|
-- (detected at replay) and is fixed with "pql ticket relabel".
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_idmap (
|
||||||
|
record_id TEXT PRIMARY KEY REFERENCES tickets(record_id),
|
||||||
|
ticket_id TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_deps (
|
||||||
|
blocker_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
|
blocked_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER,
|
||||||
|
PRIMARY KEY (blocker_record_id, blocked_record_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_history (
|
||||||
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
|
field TEXT NOT NULL,
|
||||||
|
old_value TEXT,
|
||||||
|
new_value TEXT,
|
||||||
|
changed_by TEXT,
|
||||||
|
changed_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT UNIQUE,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_labels (
|
||||||
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
|
label TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER,
|
||||||
|
PRIMARY KEY (ticket_record_id, label)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS meta (
|
||||||
|
key TEXT PRIMARY KEY,
|
||||||
|
value TEXT NOT NULL,
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_record_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ticket_idmap_label ON ticket_idmap(ticket_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
||||||
@@ -0,0 +1,173 @@
|
|||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67ZXPWX71ND4C699C', 'T-43', '2026-04-22 22:01:13', '2026-05-07 19:04:55', NULL, '069521bcf068ff6889cee5251511446c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7SS2V5Z1M1XJGQX0M', 'T-86', '2026-05-06 13:28:58', '2026-05-07 19:04:55', NULL, '07e51e80b6df55240c465d17a9430700', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7P6Q0DG4RG4CBHFJG', 'T-67', '2026-04-24 06:34:16', '2026-05-07 19:04:55', NULL, '0b64bd846488ccf4fce74a6e14629edb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM460GRBMZMV8E5339M', 'T-77', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, '0cdd07e0992ab8eb76d6945ae1079855', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79D19C0ZTXAVPKCCG', 'T-12', '2026-04-22 11:47:03', '2026-05-07 19:04:55', NULL, '10055ea4ae6c926286eb81eb35b8ef8f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427FX3GTR3VNNKM40', 'T-63', '2026-04-24 06:34:16', '2026-05-07 19:04:55', NULL, '178d61b166cf7e8f17efc83cdf60c062', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7DV4ZS010XWZJ9A84', 'T-6', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, '17e7bcab28adfbab47be2ad9aa4e4c56', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4W194B2421P2SF83R', 'T-25', '2026-04-22 20:14:24', '2026-05-07 19:04:55', NULL, '1b888a483ec795737d7a1cf71fdbd699', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM77477EN2R5872G95M', 'T-93', '2026-05-07 06:33:47', '2026-05-07 19:04:55', NULL, '1f5f4e360943d2a903cdd7c819bfeaa3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7D8AG5AY1CW58HCB4', 'T-58', '2026-04-23 20:32:06', '2026-05-07 19:04:55', NULL, '253f8fb1458c5394eea856c885f94fff', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4M63G18VAQFG6R3XW', 'T-28', '2026-04-22 20:14:52', '2026-05-07 19:04:55', NULL, '280276cb372707c0fcdbc7de5c68f568', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7CEP425DNV3W7RFPM', 'T-72', '2026-05-05 12:53:05', '2026-05-07 19:04:55', NULL, '2c7cd24dee2e7d21a31f476af233284d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XZA5399D2EHYCVFC', 'T-5', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, '31b2ad13bb8bcc41e4d21825a232f086', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79CNBXJ2S3CFQR7VM', 'T-81', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, '32698f648acf611d10fc719f6be28bad', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM76XDA3SZMPWR8WQSC', 'T-62', '2026-04-24 06:34:16', '2026-05-07 19:04:55', NULL, '3439d016919d87e8b4860735a23de1a8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GSR5WPC2T7CJM8XW', 'T-4', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, '407e3921ca9e6d5d13e11b7f577ad591', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4PMYC2E1X99HX4MDM', 'T-84', '2026-05-06 10:16:02', '2026-05-07 19:04:55', NULL, '40ce052d36bd0270aa01f9e25c1a944a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5A8DYZ3BCJN1DEY7C', 'T-71', '2026-05-05 12:53:01', '2026-05-07 19:04:55', NULL, '43cfd9109375b0fb6a8f176a0df764a5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48MDE8ZZ82VWNY994', 'T-27', '2026-04-22 20:14:45', '2026-05-07 19:04:55', NULL, '440474d801f1b9bd05e8fbb4254c3817', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M1VZ8Z2SZ94F0EQR', 'T-3', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, '44d2e24e49ca8555a6b3327f7e954ede', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7AVABFH067XGTTCVM', 'T-76', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, '4a3e92a591238f629d18f9b10087c7f6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WXV1RKPDK810C3FR', 'T-31', '2026-04-22 20:33:56', '2026-05-07 19:04:55', NULL, '4c423ea86e8173f7fa6edddea9adbadb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62E3MNW8TBTKSR9GM', 'T-1', '2026-04-22 09:41:51', '2026-05-07 19:04:55', NULL, '55239329122e1f84e9aeac9cee14a21a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KH7VR0BMZV5SSTXC', 'T-37', '2026-04-22 21:03:40', '2026-05-07 19:04:55', NULL, '55c80e1ce022b96aab6e97e31579c302', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM42RQZVEWTF9CJSRF8', 'T-85', '2026-05-06 13:28:58', '2026-05-07 19:04:55', NULL, '6133918ee124e5502286fa0de06b5bd9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7QREFG3SBG2QPYY7R', 'T-59', '2026-04-23 20:32:06', '2026-05-07 19:04:55', NULL, '64c389eab795606b9d8b5b65877a67bc', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JH7WV2RH5DGEA2AC', 'T-19', '2026-04-22 14:08:40', '2026-05-07 19:04:55', NULL, '65ba2e99100be29287532b3390054401', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5YG22EV7BFTX5RTPR', 'T-26', '2026-04-22 20:14:33', '2026-05-07 19:04:55', NULL, '685c38f471288372eab298a106a06d66', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6T6580D8ABDVTMNZW', 'T-8', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, '6aa0a08f23546d11b37f80d54920c3be', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4VVHNKNXPYD4XWRYW', 'T-30', '2026-04-22 20:33:53', '2026-05-07 19:04:55', NULL, '6d929d2dcc64310a43b21be1a8314258', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4TQEYESK545T8F164', 'T-57', '2026-04-23 20:32:06', '2026-05-07 19:04:55', NULL, '6ff368c440149011af6cc3e2bdfe243f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM79H4MPEWW2TWQ89D0', 'T-46', '2026-04-23 20:27:58', '2026-05-07 19:04:55', NULL, '71f030d09b588292801ae8853accd90c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM70QNVQY1MQGP3A33G', 'T-78', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, '73ecd48d2d9f1cdf8e1bf6e88a8dc812', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM52JT96V5067SM0DMR', 'T-87', '2026-05-06 13:46:07', '2026-05-07 19:04:55', NULL, '740c1dcab17dbdc339750aa8e32a1281', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QKBQY7FPCNX6N28R', 'T-45', '2026-04-23 20:27:28', '2026-05-07 19:04:55', NULL, '7c312190b902337039b21f4743be8908', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5Q6AWSTKGT0P64TRR', 'T-39', '2026-04-22 21:03:40', '2026-05-07 19:04:55', NULL, '825042c21d032181c1fe6d55a29a94f9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59BAJSJ1JESDTPNER', 'T-15', '2026-04-22 11:47:18', '2026-05-07 19:04:55', NULL, '836e6112c6e1dff23772619499fad245', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7TW8EJNJ2VP306A20', 'T-14', '2026-04-22 11:47:18', '2026-05-07 19:04:55', NULL, '8496d923db0e1fa76e7b787a273e974e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5QHMB46NSHHPVQRF0', 'T-24', '2026-04-22 14:08:40', '2026-05-07 19:04:55', NULL, '8a892f3717f8da2c93f67d3170af014f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5AACHWPFWZDCJ3CPW', 'T-73', '2026-05-05 12:53:21', '2026-05-07 19:04:55', NULL, '8e532488915724b80881c7b2dc227de9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P00AT6KGVZ1EF60C', 'T-18', '2026-04-22 13:26:29', '2026-05-07 19:04:55', NULL, '900d00f28a29207a464017a0bd750f33', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM734YZ060Q63H40EYG', 'T-80', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, '90da3a2c5bd03b314d661362a3919506', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6JXWYYQ6MT6N8STYM', 'T-38', '2026-04-22 21:03:40', '2026-05-07 19:04:55', NULL, '91c3ef42d94e16789915ee6366f7015d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM75XRV8AQG2HEQZEJ0', 'T-16', '2026-04-22 11:47:18', '2026-05-07 19:04:55', NULL, '98bf61f1693e8b8877c2cc03c9fb120d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67JSC5RKS6M9182KG', 'T-41', '2026-04-22 21:03:40', '2026-05-07 19:04:55', NULL, '9ab8f6ffa933c87dd3153eaea452e902', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM66FTCTWHH9AQTNFKR', 'T-55', '2026-04-23 20:32:06', '2026-05-07 19:04:55', NULL, 'a7b7dc2af0426c8bcbfea6a3023a0aff', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7YHYTWJGWPFJNHEAR', 'T-10', '2026-04-22 11:47:02', '2026-05-07 19:04:55', NULL, 'a8fa7598a624ad83878db046ffa8986f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TS48DVFDVJNZ5WGC', 'T-11', '2026-04-22 11:47:02', '2026-05-07 19:04:55', NULL, 'af42494291be5910520becc10285e157', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R0WRHSJV1MVCW31M', 'T-9', '2026-04-22 11:47:02', '2026-05-07 19:04:55', NULL, 'b8d2fca6e4b3882e4cd1ec486924265b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4005W4QV0ZPBMQ02C', 'T-35', '2026-04-22 20:34:06', '2026-05-07 19:04:55', NULL, 'bbbe9cce785ce60416cba671cea2985a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM50DVPFP4WY74RQBB8', 'T-61', '2026-04-24 06:34:16', '2026-05-07 19:04:55', NULL, 'bbf53c20ed761296c7bd54d418b67218', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM50X0DX8XTVZEA5GN8', 'T-60', '2026-04-23 20:32:06', '2026-05-07 19:04:55', NULL, 'bc1502a8c8fe4e44c004f56e9e15b03e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6PMW57C70KBJVAV10', 'T-22', '2026-04-22 14:08:40', '2026-05-07 19:04:55', NULL, 'be0ae61f02897da33e8a9b2d6d1b002e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GHHRANK5532VJVJR', 'T-34', '2026-04-22 20:34:03', '2026-05-07 19:04:55', NULL, 'c042cabf5814a596e1582a8a85138543', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM606BMYDDGRSJBVPG8', 'T-70', '2026-05-05 12:52:56', '2026-05-07 19:04:55', NULL, 'c04d59ecdcc1ade801ed7f0866a3f00c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM74S58G8XZV1766VD0', 'T-90', '2026-05-06 20:38:14', '2026-05-07 19:04:55', NULL, 'c36ec6ce6ac423fa9983758304139d2b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7CEKQCMZAV751402G', 'T-47', '2026-04-23 20:28:43', '2026-05-07 19:04:55', NULL, 'c5abd99aac954b783b84f3b77d003691', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5EP8B65T0AR52TQFW', 'T-92', '2026-05-07 05:51:48', '2026-05-07 19:04:55', NULL, 'c62020a1cf82eb7ed6bb5635d5f8f0fa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QHBTA4VE6TWQT43R', 'T-13', '2026-04-22 11:47:18', '2026-05-07 19:04:55', NULL, 'd08af226653f0822b332b640dfcedde5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KX7HEQJ65HZ566DG', 'T-2', '2026-04-22 11:45:26', '2026-05-07 19:04:55', NULL, 'd1b1abb9046e230f581009daf61e7bfd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7Y0DFP66HSP073XHC', 'T-88', '2026-05-06 14:34:35', '2026-05-07 19:04:55', NULL, 'd1ea1e789ff487787076d0ca66670e35', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JZ2AKN74FKMK3MR8', 'T-69', '2026-05-05 12:52:52', '2026-05-07 19:04:55', NULL, 'd2622779cfbab03758ed02949f12fa72', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7MKCHC37G69SJGQ04', 'T-32', '2026-04-22 20:33:58', '2026-05-07 19:04:55', NULL, 'd4125c549e70d4f4d37bb43a4f3ccbd1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NS39QCDHNVVVT1R4', 'T-17', '2026-04-22 13:26:29', '2026-05-07 19:04:55', NULL, 'd732affde22ee738f13bacb127c094e7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5X2K66A0MQY2VZ7H4', 'T-83', '2026-05-06 09:17:39', '2026-05-07 19:04:55', NULL, 'da553a2c61adb1795c0ab33867dc6ba3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4Q4XW93E3WA1SD9KW', 'T-75', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, 'db0b7c934e54d06fcf33aaf168a723e4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6YBQP75NQQ4Y9DN9C', 'T-68', '2026-05-05 12:52:48', '2026-05-07 19:04:55', NULL, 'e14345ea70ff466ed3d9b8de161ea556', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6VMWWSP4BV8Q11W0M', 'T-20', '2026-04-22 14:08:40', '2026-05-07 19:04:55', NULL, 'ebf54efaf812fb838959a80b4cdcc527', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM699HAWC76SHRA7AM4', 'T-21', '2026-04-22 14:08:40', '2026-05-07 19:04:55', NULL, 'f217b0ca72240fbbe463d296f250f3b6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM64DC28XV20JJ8KW00', 'T-33', '2026-04-22 20:34:01', '2026-05-07 19:04:55', NULL, 'f7924a89ac74721c9145a511b7a1b4e9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM454GCK8ENRKRA44NW', 'T-49', '2026-04-23 20:31:35', '2026-05-07 19:04:55', NULL, 'f9fb75eb241d8edd62688d7ac3fdd25a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM57AEVK5E0GWVPGAY8', 'T-79', '2026-05-05 12:58:59', '2026-05-07 19:04:55', NULL, 'fe4c71ca925995617dcd4409caaae9d0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6RDM2EKZX132GPV7M', 'T-40', '2026-04-22 21:03:40', '2026-05-07 19:04:55', NULL, 'fe57a623da7c3fda11455f1d78ba7f4c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7162Z26FDWXG35VH0', 'T-7', '2026-04-22 11:45:41', '2026-05-07 19:04:55', NULL, 'ffa3d6a93f30550da97a3357a0b40c3c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48X0763Z9DZSM0HFR', 'T-94', '2026-05-07 19:08:29', '2026-05-07 19:08:52', NULL, '8087c73fd647b2156a0275ec7ec2ffcd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WCDTR41VN9P1EGMC', 'T-96', '2026-05-17 17:16:01', '2026-05-17 18:11:18', NULL, 'c44d6bedd77f53875b4fb7f92e8c9895', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7F3V130BQXQH6HDVC', 'T-98', '2026-05-17 18:47:13', '2026-05-17 18:55:57', NULL, 'b2543702670de76b92f98bcb3690901e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7NRKR9J1QTDSP9650', 'T-101', '2026-05-17 18:47:29', '2026-05-17 19:01:39', NULL, '8acbd73697594b2f0686c7e1f01f0b8e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QNZM15V1ZK32YS6G', 'T-102', '2026-05-17 18:47:33', '2026-05-17 19:01:39', NULL, 'c77e3fe23ababa8854065860aaaf7645', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM493QAZNJTJQHYFGCC', 'T-103', '2026-05-17 18:47:39', '2026-05-17 19:18:43', NULL, '34fae6a3452e2f3a6fc76605fb82cd85', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6MP9JD93ZE0CDGFFW', 'T-106', '2026-05-17 18:47:51', '2026-05-17 19:18:43', NULL, '52a5c071f2c90428eba13aaa8f785831', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7WW3008NZRJWJ88HG', 'T-113', '2026-05-17 18:48:24', '2026-05-17 19:18:43', NULL, 'fabd5c2006ae0e13714b1aa12ecd2e41', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6MWAKNB2NE3ZZ0XKW', 'T-110', '2026-05-17 18:48:09', '2026-05-17 19:39:12', NULL, '22d75188f931b18801e8e9015e9863a5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM60QRRNEEWG84VWKXC', 'T-66', '2026-04-24 06:34:16', '2026-05-17 19:39:37', NULL, '8b24910aba2e49638668b03f64006a5a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM42M9RK4399B4F4WSG', 'T-64', '2026-04-24 06:34:16', '2026-05-17 19:39:37', NULL, '9d3e8f627b3095e1db58e047618be710', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM65SSVGN5M36T4QNDC', 'T-117', '2026-05-17 19:28:28', '2026-05-17 19:39:40', NULL, '852007cdda3b405757c088e160798b40', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4CWANNSKNF2X5JEJ4', 'T-100', '2026-05-17 18:47:23', '2026-05-17 19:47:50', NULL, '3edd0e73ac89116392d4aab4e8180c6a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM63H3CXCKB13E3RNHW', 'T-105', '2026-05-17 18:47:47', '2026-05-17 19:56:28', NULL, '0f673c39dc8c450947f34c86e743f8cc', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM40PV7G53JMHHNYPYG', 'T-108', '2026-05-17 18:47:59', '2026-05-17 20:05:38', NULL, 'f023344206a267eefd5d2c453d3483c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4ZNR15BSANVX07N1R', 'T-112', '2026-05-17 18:48:20', '2026-05-17 20:11:16', NULL, '874a9bbe234acb55dfc20d72a2c5a361', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4W20PVMHX1BBJ4TVW', 'T-118', '2026-05-17 20:51:47', '2026-05-17 20:53:41', NULL, 'b8fbc53c7092e7b29a869f0247cd0e38', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7FG92QKNFJSCAP888', 'T-114', '2026-05-17 18:48:28', '2026-05-18 07:04:38', NULL, '2c16b22992624d00be14801c105350c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7Y9KHNVRZ41VYW1YM', 'T-111', '2026-05-17 18:48:14', '2026-05-18 07:43:45', NULL, '1c12b7ea3d82ff2bc1e5680690ee0746', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5W67PPRVA8SAJXHFG', 'T-104', '2026-05-17 18:47:42', '2026-05-18 07:53:10', NULL, 'ec883c703bad46f757d38057c71336d3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4TTAC53CQYWDQ91H0', 'T-109', '2026-05-17 18:48:03', '2026-05-18 08:07:23', NULL, 'ed187720e362af1ff3f8cae3fd0ac828', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM45DS16DX0NKMN9Q3G', 'T-121', '2026-05-18 08:07:23', '2026-05-18 08:22:19', NULL, 'ec1cbea6674c6fb5d365510587c082ec', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM614M7ES54V3SETAQM', 'T-115', '2026-05-17 19:10:21', '2026-05-18 09:30:59', NULL, '640c8f8e5a67cdb44eaabd65bf21fc04', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4RJ9K19P5AX14RHRR', 'T-123', '2026-05-18 10:29:02', '2026-05-18 10:29:02', NULL, '255468e265f300a234e8456d3a0abf51', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7FXS713CKYDZ284NC', 'T-107', '2026-05-17 18:47:55', '2026-05-18 10:30:30', NULL, '4bc77250919cd4cef2fb1bfd3438a7c6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4H5C2Z6GCBCQ85QGR', 'T-116', '2026-05-17 19:14:31', '2026-05-18 11:22:46', NULL, '972bf9cfde6de9ff37cb5cb1dcc5a2dd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM53N56Z60B4SQ5VTRG', 'T-74', '2026-05-05 12:53:22', '2026-05-18 11:51:40', NULL, '7b71c20018634be865ab843900b93eff', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AV8YXV4NYWS2ZQYW', 'T-124', '2026-05-18 11:58:47', '2026-05-18 12:51:08', NULL, 'b272f7b62db06897d71bcee86b0aef6e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KY9JVRKF22GGFMXR', 'T-125', '2026-05-18 11:58:52', '2026-05-18 15:51:09', NULL, '801eba2049b8dc046ab81f731d0caef1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78E2NAM4YK3A2AV6R', 'T-126', '2026-05-18 11:58:57', '2026-05-18 16:04:29', NULL, '6bc6a6b1f009225521ace82a6616244c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7J40S0A8Q8PC0PDY8', 'T-127', '2026-05-18 11:59:02', '2026-05-19 10:03:26', NULL, '0e2e8e90772e11cfad16ee7805a58f7e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KEY6593FMW8Y40VC', 'T-128', '2026-05-18 11:59:06', '2026-05-19 10:06:46', NULL, '9cf26209ff598d91824d59f791b34938', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM40XWGSN99DBDQDHJR', 'T-129', '2026-05-18 11:59:11', '2026-05-19 12:19:51', NULL, '618bff52db127ed5655c78c4e09f3078', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5MW2V3QCMWKMY4VQM', 'T-130', '2026-05-18 11:59:17', '2026-05-19 12:33:52', NULL, 'ab53ef037d31eb5a977cf6fe3280e126', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5ZSRZARG7SXCC71NM', 'T-131', '2026-05-18 11:59:23', '2026-05-19 13:14:41', NULL, '7339bc2840f028e45e798e8bd8c9c337', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM76Q97D8R01CRTTA9R', 'T-99', '2026-05-17 18:47:18', '2026-05-19 13:14:41', NULL, 'ff7b3f5bbb802d081c305d32b3330163', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54DENVAR46RXCCQQM', 'T-119', '2026-05-18 07:43:50', '2026-05-20 07:00:06', NULL, 'd2732a32ffbc29ddca7f9eacad2d5570', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM47ARMYK2H24KJ0DAG', 'T-120', '2026-05-18 07:53:08', '2026-05-20 16:02:35', NULL, 'fdab02033af4c3f6df800ddf3bc78198', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM56CF9W94FSFDSBKGW', 'T-97', '2026-05-17 18:47:08', '2026-05-20 16:02:46', NULL, '84c961d85f80b8ba21fc227f7d191948', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6TNXTJCQBH9VADC4M', 'T-89', '2026-05-06 20:36:42', '2026-05-22 13:37:46', NULL, '7197034866b3116490b8633fd18ff01f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4HGK6KR0314P2M32M', 'T-91', '2026-05-06 20:49:47', '2026-05-22 13:37:46', NULL, 'c1d096207b720c77ac05b1950dce1bcd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54N0ZDJRS7G6MP1XC', 'T-136', '2026-05-22 15:59:34', '2026-05-22 17:37:23', NULL, '24eae70edc48f10e227710ee77e94fb6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54G017Y29APWJTCN0', 'T-133', '2026-05-22 15:50:06', '2026-05-22 17:37:23', NULL, 'a4886b596be68f26bcf01315f2eba159', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6SRMD12DMXCX6N7DM', 'T-135', '2026-05-22 15:59:34', '2026-05-22 17:37:23', NULL, 'e18b6b13a86b6202afb93b4bae32c824', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4EQAERS4J9X9RAETR', 'T-134', '2026-05-22 15:59:34', '2026-05-22 17:55:11', NULL, '99fdef2c143698cd8dee33e5903015f5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6E3X5WWRS09GCDGK8', 'T-137', '2026-05-22 15:59:34', '2026-05-22 18:14:32', NULL, '0ae6c36aab9db692afc7b9de9d83b70b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4V1PZ0EK6G60699EM', 'T-138', '2026-05-22 15:59:34', '2026-05-22 21:49:09', NULL, '006e8c34ed9058294d4144ed2fd853ba', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427ZFSTWJ21EBK5FG', 'T-142', '2026-05-22 22:06:59', '2026-05-22 22:18:02', NULL, '93352b90d5b8532dca21609a5e6dee2c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6YWAC8SSGQBK31T98', 'T-143', '2026-05-22 22:31:22', '2026-05-22 22:36:09', NULL, 'd585cc1215d301735c9e207e08193e6e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4BV0CXWCT04Z81EG0', 'T-144', '2026-05-22 22:40:42', '2026-05-22 22:43:45', NULL, 'b8e257b9abde9da0c38fc15cb7d4ee41', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM653J6604KYDK6RT8R', 'T-139', '2026-05-22 15:59:34', '2026-05-22 23:16:28', NULL, 'e43a27d4464ce09179016a65dc702a57', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5AVSMKD15KBJYX48W', 'T-140', '2026-05-22 15:59:34', '2026-05-22 23:31:46', NULL, '2e962cad8956dff339a9c3028ff8c83a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM558PCHET90BBSHGTC', 'T-146', '2026-05-23 06:19:51', '2026-05-23 06:30:47', NULL, 'd575cf325d7b347a88ca11f516b1b715', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM47FEEMHPE8J5VVBKM', 'T-147', '2026-05-23 07:03:18', '2026-05-23 07:06:54', NULL, '2b5e6b5f67000bea0097ea86986124b6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4GDS1R8H2TW12WX7G', 'T-149', '2026-05-23 07:14:36', '2026-05-23 07:27:32', NULL, '1ffa4dc9299a04293bfa473036ed8e08', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5KN50C7A723SEKZXG', 'T-145', '2026-05-23 06:07:59', '2026-05-23 08:43:19', NULL, 'e688de6397028cc53baef88f4af4db5c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6F9XA7F2BX9P18BR4', 'T-150', '2026-05-23 09:04:40', '2026-05-23 09:33:03', NULL, '6103463406709c57456e06226486a739', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM77GWREHKA9K45P020', 'T-151', '2026-05-23 09:52:14', '2026-05-23 10:20:12', NULL, '1ee4e62532962562e7a57316eedf0d04', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7BJS5E1JJGSJ9XHG0', 'T-153', '2026-05-23 09:52:27', '2026-05-23 10:35:56', NULL, '872e6c5e27120a76b24f7c033286071e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6YSQYCE096R2SFRXG', 'T-152', '2026-05-23 09:52:20', '2026-05-23 10:43:52', NULL, '9ba6f625fd14bb95a31902b699e821e6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5B47G9GG22N9KBNEG', 'T-156', '2026-05-23 11:15:08', '2026-05-23 12:05:19', NULL, '35180e547e94880bbe7c9f73b8b28e2c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XM8EY708NAM1JK00', 'T-154', '2026-05-23 09:52:32', '2026-05-23 14:50:17', NULL, '45a2e199fca3eb06e286f98d5c8c2228', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5R9Q3T7CBMTHM2GFR', 'T-155', '2026-05-23 11:06:50', '2026-05-23 14:50:17', NULL, '578a38cb9982309cac40cd0a214d7839', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6CYT7NW4WE8ZP1TXR', 'T-148', '2026-05-23 07:03:18', '2026-05-23 15:05:29', NULL, 'edd29e766c59c65f2ca3c83700ed96f0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5V9RNW2BGT5GHRTRG', 'T-141', '2026-05-22 15:59:34', '2026-05-23 20:49:44', NULL, 'c95d953ec43d43dde07d94192342c3a9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QZ3JJF1704AV5JCW', 'T-157', '2026-05-23 20:48:31', '2026-05-23 20:57:07', NULL, '96ab8af2d5b2835a37c23b1af6c25be1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6KD2DKTGHC6CF1MJ4', 'T-159', '2026-05-24 08:53:13', '2026-05-24 08:54:30', NULL, '6d88f03a4c6268aefb7ab51411e6970f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7SPRJZ519RZK1ZPAW', 'T-161', '2026-05-24 09:24:02', '2026-05-24 09:45:07', NULL, 'e5ad416566fa75f3caf1ccf085aa2506', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5932T486Z1F1M6X6W', 'T-173', '2026-05-24 16:45:40', '2026-05-24 17:10:07', NULL, '0d564a0dc8adc327e3f9460c254499fa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AHSN3BXZFFWS0EPM', 'T-165', '2026-05-24 16:26:15', '2026-05-25 06:29:25', NULL, '879dcc70eadbc3d29a1e6f81ee0e86d4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7KA37YDBJ89GJ27H4', 'T-166', '2026-05-24 16:26:23', '2026-05-25 06:31:08', NULL, '6a6a0ba97d6331ac3441060ec28197db', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7K30Y9WAYZ3D330YR', 'T-175', '2026-05-25 07:11:09', '2026-05-25 07:25:02', NULL, '1d7a94fb62083c7c4390103f5bf29786', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6RP0Q312AZJ8S1Y6R', 'T-177', '2026-05-25 07:11:22', '2026-05-25 07:25:02', NULL, '59a180929bd8894b53a761b2dda7b4f1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7AXEWDKD4VQNQCACM', 'T-176', '2026-05-25 07:11:16', '2026-05-25 07:27:57', NULL, '231d303368c603a6e01a6da02802fbc4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4VNVEAEYBX3S9Z8Q8', 'T-178', '2026-05-25 08:10:10', '2026-05-25 08:21:46', NULL, '3f7aae66c9e487bef74fd4d93b304d12', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4DTGYPAB29MRDN000', 'T-179', '2026-05-25 08:10:18', '2026-05-25 08:26:21', NULL, '826c15b06fe0aaaf660e31042fe371bd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48P8T23ZPR0BRK6PR', 'T-169', '2026-05-24 16:26:49', '2026-05-25 12:12:29', NULL, '99d40776974ced8e57efaa135df3ea9f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM654XV2TG4K0RVV1CW', 'T-170', '2026-05-24 16:27:01', '2026-05-25 19:38:16', NULL, 'd4a19feb40528dd6d22186c442c46890', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4R8YY69YAARCVE4AC', 'T-160', '2026-05-24 09:13:42', '2026-05-30 11:05:56', NULL, '87a62aa99c4c3e3be11c031c5667ff68', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7G7MK8MP3BGQC36HG', 'T-167', '2026-05-24 16:26:30', '2026-05-30 11:05:56', NULL, 'a7343c529fc0c766f4d7c2a9530614fe', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78W48QX3JZP0QYAVW', 'T-168', '2026-05-24 16:26:39', '2026-05-30 11:44:28', NULL, '65bd7ae87632b0d65777a26af0bb31f2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6FMAHXM1XAHHCQC60', 'T-171', '2026-05-24 16:27:09', '2026-05-30 21:11:26', NULL, '556df973d835841f7e8ae0c8cd9dd310', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7ZB63YYNFXM9DQNRR', 'T-174', '2026-05-24 17:11:17', '2026-05-30 21:11:26', NULL, 'db290b95db28db6b5a90d880d8a36fdb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM71N3YMS82BAYD3M9R', 'T-172', '2026-05-24 16:27:16', '2026-05-30 21:34:56', NULL, '8fca1700a4bf028e071cf30e845ee8f1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6V6TKRPA106D5SMMM', 'T-180', '2026-05-25 09:15:58', '2026-05-31 08:49:07', NULL, '412af567b67756da2e6b438c6a4bfd45', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7WE0SD9N4HCP9BB64', 'T-183', '2026-05-25 09:26:40', '2026-05-31 09:30:11', NULL, 'f09d4e58d36e3049bbcf5d92df301530', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM55DZN2RFEVP6CG48G', 'T-184', '2026-05-30 11:42:53', '2026-05-31 10:17:09', NULL, '7f2e958614fa540d1087d3f1c84568df', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM52PRNJM86A1DZTQ1C', 'T-185', '2026-05-30 21:34:26', '2026-05-31 10:22:02', NULL, 'd7d14700bc8fb0164e6e2852b7a358cd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5HM3N07VB3RPFJCFM', 'T-164', '2026-05-24 16:26:05', '2026-05-31 10:22:03', NULL, '8bc4ad2dbf63176d9674cd014c6cce7b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4TDSA2PDCV814E3YW', 'T-95', '2026-05-08 10:48:59', '2026-05-31 11:20:21', NULL, '628386f31fcfb4e96eac7b503ab2eb4b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5316HVGDYD2W0DC50', 'T-162', '2026-05-24 09:29:07', '2026-05-31 14:17:22', NULL, '46d071266f94b404760832f3c2d88927', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM514YJBF8AY8Q4N7Q4', 'T-188', '2026-05-31 11:38:28', '2026-05-31 14:17:22', NULL, '7328143d32f30fc412c22b5d76de92a9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4GVWHMRTMQYRTRKD4', 'T-187', '2026-05-31 11:38:20', '2026-05-31 14:17:22', NULL, 'ce42be5c4b71e4c155b26e22506045f4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4DAQ2CEFESG9JGMZ8', 'T-192', '2026-05-31 12:08:42', '2026-05-31 14:46:39', NULL, '6bd69db546e3d3aadb77b5c289db817a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6S7FDAXQX32JNCSFG', 'T-186', '2026-05-31 11:37:34', '2026-05-31 16:40:19', NULL, 'eed0473280a7c582289f0fcaa6bf6dd5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM709YPWECH1E66XXD4', 'T-193', '2026-05-31 16:12:42', '2026-05-31 17:26:25', NULL, 'ffbdde83a1cd6bbe9046f686705b2e15', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6YYG4X5R1GX97TJB4', 'T-52', '2026-04-23 20:32:06', '2026-05-31 18:54:02', NULL, '1e34fa00e15b0ada663e117c7493ca69', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QPGVP54EKJPCNQQM', 'T-51', '2026-04-23 20:32:06', '2026-05-31 18:54:02', NULL, 'cc6cf69d394f87a29c685b27ec13155e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM452XPSG99PA60ZZ48', 'T-53', '2026-04-23 20:32:06', '2026-05-31 19:41:13', NULL, '22e98aa4226d3e9979abd7b7cdf7b68a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
@@ -0,0 +1,340 @@
|
|||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7MFNNCC0MMY2TCNRM', 'T-194', '2026-06-01 06:49:25', '2026-06-01 06:49:47', NULL, 'c4ed6eb84383fb6052a61f94e37c98c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4M2Z9YZ0SA81E5Q08', 'T-195', '2026-06-01 06:56:05', '2026-06-01 07:08:16', NULL, '6d199187494f2f942598092f9743285f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6NTYAB8K6T50F8W00', 'T-196', '2026-06-01 08:58:10', '2026-06-01 10:45:14', NULL, '57fadff50bee964e4d821507d0e6e79b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6HQXNNF05GXWK7BWM', 'T-198', '2026-06-01 11:11:32', '2026-06-01 11:31:39', NULL, 'f203d6089bcb5f23d81e4c3cf67b3d33', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM68APBCQTMGJAZ2B9C', 'T-199', '2026-06-01 11:38:32', '2026-06-01 12:35:04', NULL, '6fda1ce6b9f1ea55f001f1840fef1f7a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4RAKSX59W1HJCZ1M8', 'T-200', '2026-06-01 14:04:00', '2026-06-01 14:04:24', NULL, 'b2c666f841d2546d0e6f150dec9e901b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM57GY6PTG78SD3961M', 'T-201', '2026-06-01 14:25:59', '2026-06-01 14:45:39', NULL, '289f9f811f27bad8b3f01acda2651b4b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7G8QBJ2PNQ0VREN24', 'T-197', '2026-06-01 08:58:19', '2026-06-01 16:36:38', NULL, 'a29f2ef4fa8bc86eceff40c324d613d0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5A3984KFPD4NKRG6M', 'T-202', '2026-06-01 16:48:31', '2026-06-01 16:48:56', NULL, '726f989a61da913e9f41f3353e453541', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM643F7Z648KNFPT7GR', 'T-203', '2026-06-01 16:48:31', '2026-06-01 16:48:56', NULL, '736af2dbfdf6cfbc8d2683c8e0feb063', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM65R8CNFNE1MA5GGR0', 'T-204', '2026-06-01 18:48:19', '2026-06-01 18:51:08', NULL, '7685b5bd09a25bb7094a7458f292e81b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6M83TTXHRXESFZY14', 'T-207', '2026-06-01 18:48:47', '2026-06-01 18:59:19', NULL, '0fd6c0e9537080a0b8ab85f351161542', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4PH1J6ENYT4PJZRHG', 'T-205', '2026-06-01 18:48:27', '2026-06-01 19:12:01', NULL, 'e874c6bf6c97dae25404d6f1044f9c53', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5REFZXMY8ESWN0Z90', 'T-206', '2026-06-01 18:48:40', '2026-06-01 19:27:18', NULL, 'cdf5b34234372c3de0ef0c3caecabed2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4C2PSN2GVJY9JDSZG', 'T-210', '2026-06-02 18:13:52', '2026-06-03 09:00:37', NULL, '1281485b320f6c146f8af2519c0c02f3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM48QJV4N7J62436GC0', 'T-213', '2026-06-02 18:13:52', '2026-06-03 09:00:37', NULL, 'ac6cf78658e8a9ddfee7573e125377ed', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7171NRB1T82TGP5RG', 'T-211', '2026-06-02 18:13:52', '2026-06-03 09:00:37', NULL, 'bf74e45672e065ef2aa21ce85c341bb0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM54WTNQDMYT0AVR4WM', 'T-224', '2026-06-02 18:13:52', '2026-06-03 09:05:50', NULL, '16525f2ae7035719b319a6f579d5e316', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4TP6KXTB1GHKBW1G4', 'T-215', '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, '4fcb599f4b489ac8050770416737295d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7WYF8ESBSGAQF1S48', 'T-217', '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, '682a13f3d6e396600a5d51d38e9508d7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM51CNEJP52P79RDVJW', 'T-216', '2026-06-02 18:13:52', '2026-06-03 09:18:28', NULL, 'e89cf8d8a6c65f6c47ef73aa0f1a8d7d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78J2H2S0R79SSSPW8', 'T-214', '2026-06-02 18:13:52', '2026-06-03 09:18:38', NULL, '32ca757e5489e190af0dae4297b200d7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7XZQJAK31WRVQ0HGW', 'T-228', '2026-06-03 09:49:35', '2026-06-03 10:02:02', NULL, 'ce3d4e957ec8cf656f8f022e518bf8d0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7SA9TEX5CNMTG67MW', 'T-163', '2026-05-24 09:42:44', '2026-06-03 10:05:55', NULL, 'abed11805979ce7f3d996679ad7007a4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5PFAYE4XH7WV6VDW8', 'T-227', '2026-06-03 09:48:23', '2026-06-03 10:09:26', NULL, '99368eee1c22ea3cf782b52159c04dc9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM68T660K07YH3X5DH0', 'T-229', '2026-06-03 09:51:28', '2026-06-03 10:09:26', NULL, '9d77e30754feb77e0a64a4aa5d47f668', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6Y5SET5WGSS2W78F8', 'T-219', '2026-06-02 18:13:52', '2026-06-03 10:31:10', NULL, 'fae2d0c2950c6f4050c70e7c3c07a525', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6EGSD0SB7NYNSP1BM', 'T-220', '2026-06-02 18:13:52', '2026-06-03 10:59:25', NULL, '3c812d20f5da80c0b936cb59edd2704f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67ET3VQP90WRXVSMG', 'T-181', '2026-05-25 09:16:05', '2026-06-03 11:41:17', NULL, '045b971616418029b63a850050eef8a5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM758PXMJH16PA3JHFW', 'T-221', '2026-06-02 18:13:52', '2026-06-03 11:50:02', NULL, '9e906306ef56b2c22724d0b72f14ce2d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7AMEYEBTF8YGJ4BVG', 'T-218', '2026-06-02 18:13:52', '2026-06-03 11:50:08', NULL, '9c2a9480a37df7681fe4388e27345573', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GJRWZVHZF24TPPS4', 'T-226', '2026-06-03 09:37:54', '2026-06-03 11:50:23', NULL, '6bf4765285f29d4c8fce8d71472bae0c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM427BVZYN6MD7ZZX74', 'T-231', '2026-06-03 13:17:32', '2026-06-03 13:30:05', NULL, 'd6eb4f7458f0d1c72432b87a23aa60e3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5BJCK5YG3R0NEEF70', 'T-232', '2026-06-03 13:29:49', '2026-06-03 13:41:42', NULL, 'f255d56c3872bf6a210734e127a4a4bd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JR6QZDMKE167C4MR', 'T-82', '2026-05-06 08:30:15', '2026-06-03 14:56:07', NULL, 'd2669b112125f4f76041885296f5d315', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM492DTRZJK9CGQPGDC', 'T-234', '2026-06-03 13:49:44', '2026-06-03 15:04:07', NULL, '92a7cabc855b76f429217cc65fcfa308', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5GH6VP8TZA95NMYK0', 'T-230', '2026-06-03 11:15:39', '2026-06-03 15:17:33', NULL, 'eec8da81c7180e8f301196514ba54e3b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM46ANXPW02XGD3D3NG', 'T-237', '2026-06-03 15:43:45', '2026-06-03 21:29:47', NULL, 'f9b1b279c9292d892ac07b7f4ea7cef8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4W624VD4JW1GHDHAR', 'T-182', '2026-05-25 09:26:31', '2026-06-04 12:00:09', NULL, '35ccb60111678fbc43644460a31f1d61', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM56FKPV4WSPWA0KMB4', 'T-189', '2026-05-31 11:38:36', '2026-06-04 12:00:09', NULL, '3759a2e27d13bddbcc19ed9a4fffef9a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5V7GHH42RHV04DPTR', 'T-65', '2026-04-24 06:34:16', '2026-06-04 12:00:09', NULL, '544a078f04d5c926a47cbfdacb4e3e2f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5BWXW61EVYGMZD47G', 'T-191', '2026-05-31 11:58:19', '2026-06-04 12:00:09', NULL, 'd186513cc0783306b2c4e1b2e789dff7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5ABRPK2SPW8VY7RP4', 'T-190', '2026-05-31 11:38:42', '2026-06-04 12:00:09', NULL, 'fac1c8383ac95413e8885f8ee64b0d54', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM41S6RRTMTY9TYZA50', 'T-122', '2026-05-18 09:06:59', '2026-06-05 13:08:05', NULL, '600101f09173e61159a24ed44e34dd71', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM66TK8TQ1X5T9GK6V0', 'T-42', '2026-04-22 21:03:40', '2026-06-05 15:17:09', NULL, '223a9820685b3da2a6a6e19cf6ad036b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5WT3BHB8JZY77G5AW', 'T-243', '2026-06-05 15:14:25', '2026-06-05 15:17:09', NULL, 'd82988ff85cd644376a13f49e406138f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KPN4VK4EZP013NNG', 'T-244', '2026-06-05 15:21:10', '2026-06-05 15:24:35', NULL, 'f375c96bfd96b9cdd89db0cd046318f3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5YYY4FVPX9KRVHCMC', 'T-50', '2026-04-23 20:31:48', '2026-06-05 21:12:23', NULL, '581605b67cbab29fdcddbac46154308a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM66DNEK5FS9C0T4J5R', 'T-245', '2026-06-05 21:20:00', '2026-06-05 21:24:52', NULL, '577902ab47810d0f848f48c8bf9b3196', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6DH7C6GQN9WNKQNXR', 'T-246', '2026-06-05 21:28:44', '2026-06-05 21:29:50', NULL, '4ce06c5b0b8a09d452934ae8ba1e5c0b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6QCYT7JBF352YVJ48', 'T-247', '2026-06-05 21:28:48', '2026-06-05 21:30:04', NULL, 'c2fbcdc7eda67938f8d35f64a92782b4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5F4D2Q363QF7V40K8', 'T-239', '2026-06-03 21:41:58', '2026-06-06 06:44:40', NULL, '7312cd1c56d3c8d60625df7712a7deb4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5F2GC0ABFFVAH34EC', 'T-238', '2026-06-03 21:11:40', '2026-06-06 07:24:00', NULL, 'a724281049b28271d21c87776313dd72', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7ZQNDVPAPFSD9KYS4', 'T-251', '2026-06-06 07:40:43', '2026-06-06 07:40:43', NULL, '9f010efd2f1b44840ff0af4d3723a4af', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4BVE5EYM92CWGSXA4', 'T-250', '2026-06-06 07:26:50', '2026-06-06 07:49:08', NULL, 'a8c1c3f7d308c4fe005fb998b7ec6730', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7JXD3FKW91934D0W0', 'T-249', '2026-06-06 07:21:17', '2026-06-06 08:21:40', NULL, '9f43580f953cac1a27dab6e0ac2deece', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM70TW38E78FFXDHYAC', 'T-248', '2026-06-06 07:21:17', '2026-06-06 08:31:25', NULL, '577fda356a95641dd39c28a716227d1a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5NEXC0P46NJHACNM0', 'T-233', '2026-06-03 13:29:59', '2026-06-06 09:20:02', NULL, '4cea7def08ae19b77ecfdd04b11f4b5a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM78Q3VYWSE830CTVB4', 'T-212', '2026-06-02 18:13:52', '2026-06-06 10:02:03', NULL, '75bc38afe04d24ff77c2b55d9b764fe1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QYYKHPQ03H3QD61W', 'T-209', '2026-06-02 18:13:52', '2026-06-06 10:02:06', NULL, '4f782ec2f1fb76eea268247cf4cd75a0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4K2AAPK52Y8BEJ3YR', 'T-257', '2026-06-06 14:01:03', '2026-06-06 18:58:25', NULL, 'd79886881baf9d88ff31ec2970da2712', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5KYAV8TMH3Y3FPRSR', 'T-23', '2026-04-22 14:08:40', '2026-06-06 19:06:30', NULL, '9b456adde02b184d5d46652aac210af9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM72ACQSDBJTKRBC58W', 'T-223', '2026-06-02 18:13:52', '2026-06-06 19:24:44', NULL, '7909a9620aa2a05d6a02b36f030f3641', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM620F5ENRYNT9S0JDW', 'T-222', '2026-06-02 18:13:52', '2026-06-06 19:24:44', NULL, 'b58b0643ed78d32df526e765a076b2eb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5DYC7CRP8TMHADW8W', 'T-225', '2026-06-02 18:13:52', '2026-06-06 19:37:47', NULL, '6d2670282a9f66635c2fccaa20162209', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7XMQ44AVCAARQZX14', 'T-208', '2026-06-02 18:13:52', '2026-06-06 19:53:07', NULL, '015f7fe6ec6e3b348a6157401742472b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6S7KHYPE9W7S1JHZ8', 'T-256', '2026-06-06 10:07:35', '2026-06-06 19:53:07', NULL, '2dbd4405f72911a87fd757c819b9f0c5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6WZ7DKVDFAGQ4QDMG', 'T-258', '2026-06-06 20:55:49', '2026-06-06 20:55:49', NULL, '4bcfdcf889c4bf6ca3405fa7b4857520', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7RQMN1GKEZ5JQKJT0', 'T-259', '2026-06-06 21:12:44', '2026-06-06 21:12:44', NULL, '9efbdb558a1358b67827a0814fa5c23e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5JK0RHMRAH47K8ND4', 'T-36', '2026-04-22 20:34:09', '2026-06-06 21:14:22', NULL, 'bab3e0865388263d61db6651c3e5a55d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6DSPH569T4458B8JC', 'T-260', '2026-06-06 21:46:42', '2026-06-06 21:46:42', NULL, 'e45747cbef04e469b21ef0b4f2a3122f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7GJW4V3CXMMXXV988', 'T-261', '2026-06-07 08:03:10', '2026-06-07 08:03:10', NULL, '54c9a91b6b4408f05c85ab0afb7daf47', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7GCVGCH9RMGYHENCC', 'T-54', '2026-04-23 20:32:06', '2026-06-07 08:03:17', NULL, 'ed036c636484f9b724fe82dace896d49', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4QW8VH454J8V3E174', 'T-252', '2026-06-06 08:28:43', '2026-06-07 08:32:36', NULL, 'cb647a08e949e13f6386fefbb99c8c6e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM63WP564EZRERJHVCM', 'T-255', '2026-06-06 09:56:23', '2026-06-07 08:51:08', NULL, 'e2aa43fb1e6a1c9c28ebd1fe2ab6bd79', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM74JAV0MJMB4VQNTRG', 'T-268', '2026-06-07 09:35:03', '2026-06-07 09:36:59', NULL, '796bd5eff55061d92fe00b3c4b15d3ad', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6P9YQ5V7WS6RFJNHW', 'T-269', '2026-06-07 09:44:17', '2026-06-07 09:51:32', NULL, '6fc792db7c0d2ba8f8c73c1e1960faf6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4XBRZJ6DEHFWREWC0', 'T-271', '2026-06-07 10:42:32', '2026-06-07 10:42:32', NULL, 'a7a8244eab996f86026f60edd5969de6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM67PDXAFTPPW7B1WDR', 'T-272', '2026-06-07 10:42:38', '2026-06-07 10:42:38', NULL, 'd3fcdcc97810a9b5f6b0624a3507c952', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM40JE9MZZWCXC91THG', 'T-270', '2026-06-07 10:23:13', '2026-06-07 10:43:18', NULL, '014c8442d8f19f6cc075ad8fc27ce9ed', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM551VZ2NYV6PD0XQRC', 'T-48', '2026-04-23 20:30:09', '2026-06-07 15:40:06', NULL, '8389d1a6a5d2db863bda0f7405d9496a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM71P14PAF7K4QE61G0', 'T-262', '2026-06-07 08:10:42', '2026-06-07 17:41:11', NULL, '561c4e90d842e6ac1a22dcacd7a5e33f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5W6VN98RQM6S22X28', 'T-274', '2026-06-08 07:26:13', '2026-06-08 07:46:46', NULL, 'd9177bbb472fd16a13d4f23e0cd70344', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5TWC00GW0P3X02HZW', 'T-276', '2026-06-08 07:46:23', '2026-06-08 07:53:32', NULL, '1b77c5f3a8d66247532ead2164b6b37f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM60PAS5RJ55CZGPM1G', 'T-277', '2026-06-08 08:32:30', '2026-06-08 08:34:47', NULL, '70e24eabce743397720db9d6029a3337', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7XXSERDHKR0EEH3N4', 'T-263', '2026-06-07 08:34:02', '2026-06-08 08:45:23', NULL, '1cb588e500a902d2b880f3004c5c33b4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM45HHRBCRMV2166Y6M', 'T-266', '2026-06-07 08:41:13', '2026-06-08 09:04:12', NULL, '9162b1edab8984a25660f0fdcebcd41d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5YYMMKFD5Z8WG9F60', 'T-264', '2026-06-07 08:40:25', '2026-06-08 09:25:50', NULL, '4b9c66ff7114ce85456f57f6d1c58d7b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4Q1Q97CHA0XNK2G4W', 'T-265', '2026-06-07 08:40:33', '2026-06-08 10:09:14', NULL, 'ff24fcb74089501588a4bfcfa62c9aad', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7ZGZ9GQ5W1MKV00Y4', 'T-267', '2026-06-07 08:42:53', '2026-06-08 10:09:21', NULL, 'd860955c7a7030d4c1c2ea98e5447fdf', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM55CV3VDYS88VBJZ60', 'T-273', '2026-06-07 17:39:10', '2026-06-08 11:44:27', NULL, '02cd1eaf484bd3adef09a71a7408674e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM59DG2WADJ9A0JFD1W', 'T-281', '2026-06-08 11:46:11', '2026-06-08 11:49:36', NULL, '1d9df18227de229f12bda189c4081353', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6K1QRC911JMQ9C960', 'T-283', '2026-06-08 13:39:51', '2026-06-08 13:44:57', NULL, '56929fab7dc064046853959720d43b8b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6A6A56VFSVRRBKMP0', 'T-279', '2026-06-08 10:21:20', '2026-06-08 14:12:46', NULL, '1023e2106149f0366bf3896635ec44c4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KFHAS1WZFGBJ6JN4', 'T-284', '2026-06-08 14:55:43', '2026-06-08 14:57:15', NULL, '75d5f69fd00e63d09e707ad1e8338853', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6GZ55VD4SAZZ6XXP4', 'T-285', '2026-06-08 15:22:32', '2026-06-08 15:37:29', NULL, '994bf6438e27af887c2f3d247e76d576', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7W2MWZ45YNK7TJGC4', 'T-282', '2026-06-08 13:39:15', '2026-06-08 15:42:01', NULL, '9d5f153703ebeae7f011f555f380ef6e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5AAA9WW54JGP83HGW', 'T-275', '2026-06-08 07:28:34', '2026-06-08 16:52:13', NULL, '886bd74d7ec01145f8acb5c7d9397307', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6NNRR61E8P6GHXABG', 'T-289', '2026-06-08 20:16:22', '2026-06-08 20:16:22', NULL, '6c2022166a2139a665912c3fe6d4802e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4501EBPDFDH84RJ5G', 'T-288', '2026-06-08 17:52:51', '2026-06-09 06:19:01', NULL, '16b1c85fab4273ebe7c9cfb9b9800e3e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5R93N5J6RNVTBRB28', 'T-286', '2026-06-08 16:30:27', '2026-06-09 06:19:36', NULL, '22c1b0f40e3e3344f0c624af618bdaff', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM44CKN5QQGFKP1KWZC', 'T-290', '2026-06-09 07:15:14', '2026-06-09 07:15:14', NULL, '53ca5591666fa7c01d90174bf28ecf4b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM45BSF1B0R0JA1Z7FC', 'T-291', '2026-06-09 07:15:22', '2026-06-09 07:15:22', NULL, '79e9f769c9313f0bc63d5c8c8a1ee641', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5E41Q8TX8X55X4MZ0', 'T-29', '2026-04-22 20:17:26', '2026-06-09 10:46:41', NULL, '93ab2ce409ff22e37a756e41553c0a69', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM50BPNDT50PM24ZVA4', 'T-278', '2026-06-08 09:20:00', '2026-06-09 15:03:23', NULL, '0c340b4aeb41ddaa858ae18888207b2e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4BD8PXDRHBF001200', 'T-292', '2026-06-09 14:57:32', '2026-06-09 15:09:05', NULL, 'b907503e714ddc775257c90330c25d2f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5DM43Q9HX352STN3M', 'T-295', '2026-06-09 15:26:00', '2026-06-09 15:26:00', NULL, 'c93802bd37eb8dfe981c74cfde3f24c4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM42WW0SY3XEXKE8PK8', 'T-293', '2026-06-09 15:12:15', '2026-06-09 15:36:15', NULL, '55da76c0ebfc56f44cb4096a2a17b9c6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4GN07FN8GAXZ20YAR', 'T-236', '2026-06-03 15:31:01', '2026-06-09 15:55:06', NULL, '18d3d9bc2bc268d007d27c4cc20fcea8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM61SRVBDRFFN2S80T4', 'T-254', '2026-06-06 09:32:54', '2026-06-09 15:55:06', NULL, 'ae31cf118f94e93699eed5f0ac0eee7c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM63TRGBFRWK9W2WA98', 'T-296', '2026-06-09 15:43:58', '2026-06-09 16:34:46', NULL, '405de86b123fc1aeccf6f444a36bbf36', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM72SHY93S36VM9G6D8', 'T-294', '2026-06-09 15:18:22', '2026-06-09 16:34:46', NULL, 'baa483c978c2744aaf95035de3809048', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6RXN6HW6XTEHKYQDG', 'T-297', '2026-06-09 16:01:09', '2026-06-09 16:34:46', NULL, 'f228757d5b5ed41b7cf90b6035e09dda', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7K1FN7KD8S5ZVX2VM', 'T-299', '2026-06-09 16:42:47', '2026-06-09 16:42:47', NULL, 'a2fdfc4298353c34568d42e71c2786e6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM53HQD6YV754GKBA60', 'T-44', '2026-04-23 20:25:26', '2026-06-09 16:56:55', NULL, '75a46ae8c87aa5a9a27e513b4ea65e58', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM62FKQQD0B9B80PFY4', 'T-158', '2026-05-23 20:48:38', '2026-06-09 17:16:34', NULL, '1282d8b5cb009f639f7c7a14e69ef2b3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7D5DMYF5X92Q55CBW', 'T-235', '2026-06-03 15:17:29', '2026-06-09 17:16:34', NULL, '1bccb4cf47ba2a1a72e4f65a214e2f78', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7W0NPAEG3KWNFY9DR', 'T-132', '2026-05-22 15:45:15', '2026-06-09 17:23:25', NULL, 'cf1709ddff1d13a7b4adb0dc193b319b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7F2TBJJV1F2KP7XR8', 'T-300', '2026-06-09 20:02:41', '2026-06-09 20:03:08', NULL, '6f1c204fc4f81403ba50e9e7ecff7241', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6048VEGFDNEBHFMM4', 'T-301', '2026-06-09 20:04:29', '2026-06-09 20:04:54', NULL, '89490f3e4d3e09714b70f0e35c726038', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4AE2GEF6BXSGKRMGC', 'T-242', '2026-06-05 10:17:47', '2026-06-09 20:07:30', NULL, 'c570cc4f2808f31192d947affb3392a0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM42VPM50VKAWXBCAM8', 'T-253', '2026-06-06 09:32:53', '2026-06-09 20:17:04', NULL, '47b9d1a167b65553a14ede7a5a53f851', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM7H8JWCP59WQVD0FW4', 'T-302', '2026-06-09 20:24:54', '2026-06-09 20:25:49', NULL, '8e04d93f6163a8f54965bc5988dae31c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5QJC039TMDF5JGMXC', 'T-240', '2026-06-05 09:38:46', '2026-06-09 20:27:17', NULL, '4879c042965effced12e608af5739659', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM531VE0C6N36AT12SR', 'T-241', '2026-06-05 10:02:31', '2026-06-09 20:34:30', NULL, 'b7de744d4e5292306b1fa64bcc3ba1aa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4K1MTP2MHRKKNXBFM', 'T-303', '2026-06-09 20:41:22', '2026-06-09 20:41:22', NULL, '1adc6db2fcc64d6fd36ad0406939a8d7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4BRWWPB4R06Q31XV0', 'T-56', '2026-04-23 20:32:06', '2026-06-09 20:57:53', NULL, '5a394b49d98e119d21b637745798fd8b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM6SK3D1QYACBPHHBZ0', 'T-287', '2026-06-08 17:12:49', '2026-06-09 21:21:08', NULL, '7d9537b53ade941ecd8a8efadd591c17', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM4KS233FGZE9H7ABWR', 'T-304', '2026-06-09 21:22:28', '2026-06-09 21:22:44', NULL, '252c572a5954883d0e5e71406b092a7f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM50S6WRD81V3Z0NH1M', 'T-298', '2026-06-09 16:06:41', '2026-06-09 21:36:05', NULL, 'f8666523eaf2642b918f6846e2801539', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB0TNQM5YNEQM1WY25BV7TD8', 'T-280', '2026-06-08 11:29:22', '2026-06-09 21:42:59', NULL, 'e9859dd425e0ac667ddbce721415572e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB16FJ7KXGFHQXEG88MYRFTG', 'T-305', '2026-06-10 08:15:39', '2026-06-10 08:15:39', NULL, '288b0c9d74e98c2ac42ee25d3369f689', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB16YM1Y910T07Y1Y22MGTEM', 'T-306', '2026-06-10 08:17:42', '2026-06-10 08:17:42', NULL, 'af36af77224b697a61cb5447955605e5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB170DJA02EH2E8HMH7X7SS4', 'T-307', '2026-06-10 08:17:57', '2026-06-10 08:17:57', NULL, '882cca1753c2ede7bfe2aef142545b76', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB1Q1Y3CYJHD7W5F68VDB6T4', 'T-308', '2026-06-10 09:28:04', '2026-06-10 09:28:04', NULL, '5050ff0e69b24a93f5b7e96c8a9fa47e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB1S7613SYF0M9XQT5JNWM40', 'T-309', '2026-06-10 09:37:31', '2026-06-10 09:37:31', NULL, 'b4f48310ea6b0f49f83c46e3bc5b7ad8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB1SJKA7KRCQMZE41SPQG780', 'T-310', '2026-06-10 09:39:05', '2026-06-10 09:39:05', NULL, '9088122bf9d5e04ca8a7fee3bf031a53', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB1XDWKQ594ET4GDYEFK5ZJ4', 'T-311', '2026-06-10 09:55:55', '2026-06-10 09:55:55', NULL, 'ed03464125d09ff5f23913e6247064e3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB1ZFJK6J2GSV4SA69QF730C', 'T-312', '2026-06-10 10:04:53', '2026-06-10 10:04:53', NULL, 'dd22af12b333c13376b23aa5381ea2d7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB234WP4Y6Q16A0HFW8BSXMG', 'T-313', '2026-06-10 10:20:54', '2026-06-10 10:20:54', NULL, '9b7abb73ea56cfdad2039303a8935897', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB23Z52EVGQ4ZDAQ5BVAJ13R', 'T-314', '2026-06-10 10:24:29', '2026-06-10 10:24:29', NULL, 'f8b89421a13f620c2a0e76bd780db5a2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ACSDBDZARV3NNGYD9NYYR', 'T-315', '2026-06-10 10:52:34', '2026-06-10 10:52:34', NULL, 'd0521ab80265d66c99c803a8714e8f02', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2AD3HPR3HXSVASVZEX8PK0', 'T-316', '2026-06-10 10:52:36', '2026-06-10 10:52:36', NULL, '5beb005b263eb4c5bb10ffc6e2fc0100', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2EDCBYRBDSV9V1PJ1KE3CM', 'T-317', '2026-06-10 11:10:07', '2026-06-10 11:10:07', NULL, '4d4a02ab95987e3ebb134a2f0173b4a1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ERREMEEF26KKHGNZBWW64', 'T-318', '2026-06-10 11:11:40', '2026-06-10 11:11:40', NULL, '31820aadd1f19f9dd0cf931dae565abc', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ESCR4V6V07CRH18FBCDN8', 'T-319', '2026-06-10 11:11:45', '2026-06-10 11:11:45', NULL, '12c5a57fb83444410cca98a802e9ba6f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2ETJQP0CT6X7W3CWZ6NS9G', 'T-320', '2026-06-10 11:11:55', '2026-06-10 11:11:55', NULL, '2266e362f144e4fd97403e1d1abe3eb4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2EV29HSK6EJ5VF50R87VC4', 'T-321', '2026-06-10 11:11:59', '2026-06-10 11:11:59', NULL, 'd48b6bd9f0c8289c95448dda6865d666', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'T-322', '2026-06-10 11:17:17', '2026-06-10 11:17:17', NULL, 'f33b1db4b67a0521f02c5c49fcfa8e6f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'T-323', '2026-06-10 11:17:23', '2026-06-10 11:17:23', NULL, '0738a8da475a6d8d49132d1e4e753775', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2J2HWD66QAFDDRRWS5NM48', 'T-324', '2026-06-10 11:26:07', '2026-06-10 11:26:07', NULL, 'd8aa9ae4522d97b70331c42b8ab7a365', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2T11GCV1EV07DYD5BZENTM', 'T-325', '2026-06-10 12:00:52', '2026-06-10 12:00:52', NULL, '47b8f31d9337c5bbc6476d62c7f6ed4d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2TY91VHK7TPKPMZ11EG3TM', 'T-326', '2026-06-10 12:04:51', '2026-06-10 12:04:51', NULL, '348dee79d9d3fe0a8b260c1f9c47a289', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2W4G9K8ZF782W7H2TM5XA8', 'T-327', '2026-06-10 12:10:04', '2026-06-10 12:10:04', NULL, '967aab6bc692754a5d3a192cb0008871', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB37JZSFZKWPK9PDFYJY2YC0', 'T-328', '2026-06-10 13:00:06', '2026-06-10 13:00:06', NULL, '553b6683bbcddfbbab39ee545a99c98c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DHCTP001YCHFP39XER0ZM', 'T-329', '2026-06-10 13:26:06', '2026-06-10 13:26:06', NULL, 'a7b63cf73534de82c953d3029251b5e4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DJZDDZ00BSA04B660RS7M', 'T-330', '2026-06-10 13:26:19', '2026-06-10 13:26:19', NULL, 'c7ef552dc6d7fc2a5e312b20939a2987', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DKQQJ583944DG8561VQ3G', 'T-331', '2026-06-10 13:26:25', '2026-06-10 13:26:25', NULL, '002e4d81284119aecab05d180a9a41cd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DMF20SYFDT6WX2RFBQXKW', 'T-332', '2026-06-10 13:26:31', '2026-06-10 13:26:31', NULL, '38d661bbd4a937daf395f82074cf8d12', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DN94MBCTYJW17ZCYVSXE0', 'T-333', '2026-06-10 13:26:38', '2026-06-10 13:26:38', NULL, 'c710c528662f92c6b7416b7163c8e99f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DNQZKV20F7YG5PJH8V8SM', 'T-334', '2026-06-10 13:26:42', '2026-06-10 13:26:42', NULL, '7f774dc51ae344eddfd42c2149887d56', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DP48FS33CQGRDF7EB9GT0', 'T-335', '2026-06-10 13:26:45', '2026-06-10 13:26:45', NULL, '1cce32ce77997202bf74c69426c29ab9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DQEMTDHF8SV27AKAB8JHW', 'T-336', '2026-06-10 13:26:56', '2026-06-10 13:26:56', NULL, 'b988abcd2cef0dbd6adbc56502f676ca', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3DWCJSGZH9WYDNFWZBAYYR', 'T-337', '2026-06-10 13:27:36', '2026-06-10 13:27:36', NULL, '94b0ebd244a6794e0e4e5a868b38d67f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3JAXDKZMS0805MMEYB6820', 'T-338', '2026-06-10 13:47:04', '2026-06-10 13:47:04', NULL, 'be9b536d471a6008cc854092dfa6aaa4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3JM0AXK1CTWD720RV1AVZ0', 'T-339', '2026-06-10 13:48:18', '2026-06-10 13:48:18', NULL, 'e76a2ce5d3149bb7ca0ec8a45f5c57a2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB3KS499THAD899M0NWN7E3R', 'T-340', '2026-06-10 13:53:23', '2026-06-10 13:53:23', NULL, 'bdd164a73576f6ca5151c8a62640526f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB44SKPKTHFMV6WD28GZYPXM', 'T-341', '2026-06-10 15:07:43', '2026-06-10 15:07:43', NULL, '113520f8f3a640fa2f470200ea9f45d8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB493JEW32CH0H3771TNHF7G', 'T-342', '2026-06-10 15:26:33', '2026-06-10 15:26:33', NULL, '13a646741953f113356c4bcda162c3c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4FDREHRYRR7B9ER72KCQKC', 'T-343', '2026-06-10 15:54:09', '2026-06-10 15:54:09', NULL, 'e48d2b913bb03202409c6568d9bc11a5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4J5E6W983P1S7BE0FDPSMM', 'T-344', '2026-06-10 16:06:08', '2026-06-10 16:06:08', NULL, '481e82dfab98c20cd37c77a3e0c16668', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4RD1DDSYM4J7WYEGTXARB4', 'T-345', '2026-06-10 16:33:23', '2026-06-10 16:33:23', NULL, '9f26d5036c05057d4bd0fc53ddaddafd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4VG3N3YJSV8G7M1HFSYW2W', 'T-346', '2026-06-10 16:46:54', '2026-06-10 16:46:54', NULL, 'a64940cb0b4ec4fb489eac27065dc447', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4XCM5KBXDDSCWJ37GPYG3R', 'T-347', '2026-06-10 16:55:10', '2026-06-10 16:55:10', NULL, '9d40226dbc6136072d2d5d0eda71f141', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB50YE6S6YWNP2ZSFWES9B2W', 'T-348', '2026-06-10 17:10:42', '2026-06-10 17:10:42', NULL, '8bb5ad92551f272417840869a0774668', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB58X0TFJ02YTMVPD0D9Q838', 'T-349', '2026-06-10 17:45:28', '2026-06-10 17:45:28', NULL, '0b12f14fa83254ab113c870531628359', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB5CW7JPT6BR2RWMNYVCXJ50', 'T-350', '2026-06-10 18:02:50', '2026-06-10 18:02:50', NULL, 'a5c0c22d84621b14a5208317414d6026', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB5HMYDXP62RKH3HP55T6AYG', 'T-351', '2026-06-10 18:23:41', '2026-06-10 18:23:41', NULL, '9d2da44c16c5aa38c0a36e4b00ef5f15', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB5M14B76B31654D959XM5AC', 'T-352', '2026-06-10 18:34:05', '2026-06-10 18:34:05', NULL, '3fe3e1d5fb7c0fbd084b45116575ad98', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBAWHM1SQ1686ZJ8JQCFQ1ZW', 'T-353', '2026-06-11 06:50:21', '2026-06-11 06:50:21', NULL, '53374633101d04f94981baaf4f2e0315', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSJYQFDNKP4KA1JAEDSS8W', 'T-354', '2026-06-11 13:36:51', '2026-06-11 13:36:51', NULL, '32bb5d359401599022a8771031d8a08a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSKGAHYHH2NPZK8B6EV4D4', 'T-355', '2026-06-11 13:36:55', '2026-06-11 13:36:55', NULL, '2eb6809e958613a924b35e080ab17609', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSM0PRGYR61R0NWYAT9VDC', 'T-356', '2026-06-11 13:37:00', '2026-06-11 13:37:00', NULL, 'bdb597080218a3e8783f6c5cf74c529a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSPECQ0FPKB9SYTD7KZSBM', 'T-357', '2026-06-11 13:37:19', '2026-06-11 13:37:19', NULL, '96cf88e036dc3a45487cdbffff26cdde', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBDSQ2GBSP0ZH4RHZG2PMR0R', 'T-358', '2026-06-11 13:37:25', '2026-06-11 13:37:25', NULL, '2a656aaec54bf50c34c7e28347b1fb29', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBGHNEQTAEPGNJKN42C1E8', 'T-359', '2026-06-11 21:54:36', '2026-06-11 21:54:36', NULL, '1930fad7b18c79cf97d913d8372b77bd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBJ5T7HAQ9CA8XQMX43A2C', 'T-360', '2026-06-11 21:54:49', '2026-06-11 21:54:49', NULL, '1ffef3c00cdca28566ab67a11ec17e53', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBKK2TZQK683J8FS0ZH5A4', 'T-361', '2026-06-11 21:55:01', '2026-06-11 21:55:01', NULL, '5f8bdede98496496bf031a40a09dee16', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBN5F0F8SDF15P21DNKT1W', 'T-362', '2026-06-11 21:55:13', '2026-06-11 21:55:13', NULL, '610e74eb7b4ff9db3949ed01a0268380', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBPQE4J4YBJX92812ZK6DR', 'T-363', '2026-06-11 21:55:26', '2026-06-11 21:55:26', NULL, '5daf7bcd9ccdc37f8aed531ef12d395f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBR4636GSRJBWFJDAZ6ZA0', 'T-364', '2026-06-11 21:55:38', '2026-06-11 21:55:38', NULL, '025de46ba9e8d005fd8b1f74687cd8b6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBSG6356MZJ2DCCCSBMBGM', 'T-365', '2026-06-11 21:55:49', '2026-06-11 21:55:49', NULL, 'b366b41e4737a2761a01284fd7dd44e0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBV0465906BY3QFAY9F1YM', 'T-366', '2026-06-11 21:56:01', '2026-06-11 21:56:01', NULL, '8a75dc7dea83a0e643d1912bda46dd57', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBWE2W1226T58CX37E50HC', 'T-367', '2026-06-11 21:56:13', '2026-06-11 21:56:13', NULL, '578b51eafd19044dc0e2720f6e55d633', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHBYTJ4E7ZBY6DWWNT1S16M', 'T-368', '2026-06-11 21:56:33', '2026-06-11 21:56:33', NULL, '0df409c83fe28af2d49a156118ed6ece', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC0HYRZ86CWW0DDQJ5CAQM', 'T-369', '2026-06-11 21:56:47', '2026-06-11 21:56:47', NULL, '7f47ddc3e84f9fea915200992a5a0baf', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC2NM7AYKENZ0ZD49HAX1W', 'T-370', '2026-06-11 21:57:04', '2026-06-11 21:57:04', NULL, '1908b7c0903c389ad5b743fb89ca32e0', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC46SEHH8NQY481VMGK66R', 'T-371', '2026-06-11 21:57:17', '2026-06-11 21:57:17', NULL, '2095f10159561a5e81b2a9b990c79fa2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC5ZE4EZEGXK8YY8J86CM0', 'T-372', '2026-06-11 21:57:31', '2026-06-11 21:57:31', NULL, '9d22f370e726af56d47d6c8acd93bc87', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC7KDFW07S8WTCC3MD71J0', 'T-373', '2026-06-11 21:57:44', '2026-06-11 21:57:44', NULL, '231c399183a83e569c0645e1d149625f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHC90B72A270CAKA7AP1ZX8', 'T-374', '2026-06-11 21:57:56', '2026-06-11 21:57:56', NULL, '9832ac0b3e0bebd85f3271a5ea96d4ed', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCAFKK334YNJXZJQG4J6AW', 'T-375', '2026-06-11 21:58:08', '2026-06-11 21:58:08', NULL, 'de3569d098b5c4cf6a3d49ee3d33d1c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCC6AR37VTF4SY8DR99JHC', 'T-376', '2026-06-11 21:58:22', '2026-06-11 21:58:22', NULL, 'fe23c94d8971d21963a2b2e2739e05a3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCEC25337J2AXXQNST56Y4', 'T-377', '2026-06-11 21:58:40', '2026-06-11 21:58:40', NULL, '1585df7f3826ddbcef8a030ffd1e0890', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCG84F4SPFW111CC4K26A8', 'T-378', '2026-06-11 21:58:55', '2026-06-11 21:58:55', NULL, 'c6b0d9d124401f1d2bdc403567cbfdf8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCJEYHC91PMVNVWVHBR2RG', 'T-379', '2026-06-11 21:59:13', '2026-06-11 21:59:13', NULL, '0d9aed402c9840ef6fb75edfcfcbc3f4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCM1RBAF72SCZBKRTXJSYC', 'T-380', '2026-06-11 21:59:26', '2026-06-11 21:59:26', NULL, '1a0d767f30c9bc0e9c96f39d468ca67b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCP03EJ9CDBGZGRPD19N8W', 'T-381', '2026-06-11 21:59:42', '2026-06-11 21:59:42', NULL, 'cfac236e079164f9588d936f5101c71c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCQHZQ0NKY1VRWWPSNZT84', 'T-382', '2026-06-11 21:59:55', '2026-06-11 21:59:55', NULL, 'b54be44ec4cfbbc649324471a5e2141f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCST6CQ449VJGAP6C5KZ5W', 'T-383', '2026-06-11 22:00:14', '2026-06-11 22:00:14', NULL, '0e18de4e94e4fcf36fc40de763522cbd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCVPGCKEGDC54KKQ120SRM', 'T-384', '2026-06-11 22:00:29', '2026-06-11 22:00:29', NULL, '57d7b6a6c05791acadd1cebe611c8991', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHCXFF5V1RT6QJETS2K4C0G', 'T-385', '2026-06-11 22:00:44', '2026-06-11 22:00:44', NULL, 'ebda2dd9c7dfe92bab2260dc34212ac4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHD098CV2N73823KX4Z99P4', 'T-386', '2026-06-11 22:01:07', '2026-06-11 22:01:07', NULL, 'de90501f2d4be80231651d25d04f4649', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHD2FWTDFYA00W4QXTE41M0', 'T-387', '2026-06-11 22:01:25', '2026-06-11 22:01:25', NULL, '8a247364a872c223b37682c6496d3920', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHD4QYHYRTK0SGRZCBSHSQ0', 'T-388', '2026-06-11 22:01:43', '2026-06-11 22:01:43', NULL, 'cc238ee850d4d0ed90d05b9a42c8d506', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHD6FQMXMQQQ877KMNCK6QC', 'T-389', '2026-06-11 22:01:57', '2026-06-11 22:01:57', NULL, 'bb0657e304f4ad1445d756ef7170c62d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHD8F2NBEFZNPKSJ9W253J0', 'T-390', '2026-06-11 22:02:14', '2026-06-11 22:02:14', NULL, '35453f0d8c7e0fb89c243481f870de03', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHDAK04ZA0PBT69ZWNBXPSR', 'T-391', '2026-06-11 22:02:31', '2026-06-11 22:02:31', NULL, '0647245b4da95532bb3abd6f20cd87de', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHDC7B2MFQZVR1K9E30FXDR', 'T-392', '2026-06-11 22:02:44', '2026-06-11 22:02:44', NULL, 'a1612ff75df3d134b8e05c716d24ebfe', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHDE5A3965GNRFS5WPZW878', 'T-393', '2026-06-11 22:03:00', '2026-06-11 22:03:00', NULL, 'f8f29fb8b31cc8afdd8af989c3f711f1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHDGPXQN31NNRPJ00PFRAG4', 'T-394', '2026-06-11 22:03:21', '2026-06-11 22:03:21', NULL, 'f9cee5dc96cedfabc3eaaf7352e732c8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBHDH8TE9MJBXZ4GQ5YT10JM', 'T-395', '2026-06-11 22:03:26', '2026-06-11 22:03:26', NULL, '382a5742e32da0f38c1e143715a0b656', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBJAXQHCKHS8ZSDZNM9NH7QM', 'T-396', '2026-06-12 00:11:50', '2026-06-12 00:11:50', NULL, '20577481e56f82bb0df9e56a266303c9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBJM6XXQZ3EMGRC13XRYVBEM', 'T-397', '2026-06-12 00:52:25', '2026-06-12 00:52:25', NULL, 'bf89e25b384be60faa65e9eb1ec2fab9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMV7Y13PAYKZC0WB4FQXKC', 'T-398', '2026-06-12 03:15:00', '2026-06-12 03:15:00', NULL, 'd0ed46ee279c148f1d76683e86e0d4aa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKMXSVCE98K1H76N00TYCQR', 'T-399', '2026-06-12 03:15:21', '2026-06-12 03:15:21', NULL, 'eacf3522aeb2bccbaf006c9703b9794d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKN09R21H3AWR2Q2ZTSGNSW', 'T-400', '2026-06-12 03:15:41', '2026-06-12 03:15:41', NULL, 'a7971f428145d04ae82d4cd89f3eeb9d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKN2MP35NPPK1BRDYY2M428', 'T-401', '2026-06-12 03:16:00', '2026-06-12 03:16:00', NULL, '29980034db5fe381473b156ece7d8a1a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKN4QVFVE51MY2N0CWCVXHM', 'T-402', '2026-06-12 03:16:18', '2026-06-12 03:16:18', NULL, 'c65717bf20ea6886ef7a86f5cb4b2929', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKP67X1Y1FEE9T5R0E5DA9C', 'T-403', '2026-06-12 03:20:52', '2026-06-12 03:20:52', NULL, '372a686b214820b5d093b11b9f3d57a5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKP8KFAF526ZNXBQS98DPPG', 'T-404', '2026-06-12 03:21:11', '2026-06-12 03:21:11', NULL, 'c479a9dea6687b553bc638a9849cc5de', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKPAZR4XEV8YW3PVR2XJBFC', 'T-405', '2026-06-12 03:21:31', '2026-06-12 03:21:31', NULL, 'e4e1695f838b8fbf02aae49a6f2df4fe', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKPD85PFBPJJTQ0WS3PWWXR', 'T-406', '2026-06-12 03:21:49', '2026-06-12 03:21:49', NULL, '689352238d2050a3769b2a9613f0a793', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBKPFTC7H5NY0XHBTEGF8XQ4', 'T-407', '2026-06-12 03:22:10', '2026-06-12 03:22:10', NULL, '129d2b3c31022d53025a3e28169a060e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBN3VTK2MYQQ173MSJN6E1DM', 'T-408', '2026-06-12 06:40:25', '2026-06-12 06:40:25', NULL, '0353aaab57a40900b00883fb12e135f7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBN3VYR84023Z5XFEX9DS0S0', 'T-409', '2026-06-12 06:40:26', '2026-06-12 06:40:26', NULL, '69c280319335a8d0ef646998f4531e96', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3EZC7AJANXZVF3D91QYWM', 'T-410', '2026-06-12 08:58:29', '2026-06-12 08:58:29', NULL, '4f726d1a66d38d14018a62c8d24ffe62', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3GM6V0RZBY2PXE9ZQFR88', 'T-411', '2026-06-12 08:58:42', '2026-06-12 08:58:42', NULL, 'bdd3f8b13caf25677ac661ec29599488', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3J7TXMG0F9E2WQDENPVJG', 'T-412', '2026-06-12 08:58:55', '2026-06-12 08:58:55', NULL, 'e56d50bc6fc04f6d646f22c104e63183', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3KRWM65MD3DS251NN9YX0', 'T-413', '2026-06-12 08:59:08', '2026-06-12 08:59:08', NULL, 'b5247ea05c106500682be978a47e61ee', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3P8YERJ5R7ENSD675BX00', 'T-414', '2026-06-12 08:59:28', '2026-06-12 08:59:28', NULL, '7d973f16c99441dbba0f8df89a665b32', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBP3P91QQQDT5J50F52FPCKM', 'T-415', '2026-06-12 08:59:28', '2026-06-12 08:59:28', NULL, 'a2dea9268d44b9e8a1fd746bbb947c92', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBPQ8QNGJFFK7G24CBWQAR2C', 'T-416', '2026-06-12 10:25:00', '2026-06-12 10:25:00', NULL, 'f8c2a125e661607d5dd0c73cd2c3f2ab', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBQ4BYD4STCKCY8JNKF23Q4W', 'T-417', '2026-06-12 11:22:15', '2026-06-12 11:22:15', NULL, '15aa9b25417162126cbcde174d3537da', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBQ595H08JFTRFSR90GSZQ0G', 'T-418', '2026-06-12 11:26:14', '2026-06-12 11:26:14', NULL, '000e07ae64b08273a2d2d9f8a77d193f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FBTTMGKSYMTF8M1KQWTG774W', 'T-419', '2026-06-12 19:58:58', '2026-06-12 19:58:58', NULL, 'd2b01a2c3d1ce24cc863ac6d9d814d3d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FC2XY1T85A65YY9SG25VVEY4', 'T-420', '2026-06-13 14:51:51', '2026-06-13 14:51:51', NULL, '16ea4c9353a56798b894ab3d85fb7b56', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG3T4A7CYPTG535KVAVH6C', 'T-421', '2026-06-14 15:29:23', '2026-06-14 15:29:23', NULL, 'a28eed4b57104034c5216344a326195c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDKX4CVHWVGDAJC6X09602M', 'T-422', '2026-06-14 15:45:57', '2026-06-14 15:45:57', NULL, '5701c634f5737a2ba1612deab8df7049', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDM61KAA3GV3CVTE8PAZ8N0', 'T-423', '2026-06-14 15:47:10', '2026-06-14 15:47:10', NULL, 'ce7dfb8b9bd088b4c2e8ddfacc8d2124', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCENXW1VF7VXQX64982X171R', 'T-424', '2026-06-14 18:14:36', '2026-06-14 18:14:36', NULL, 'ecbed75dcd34c39bcbd86e60d6f4a2c2', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCENXXZFBZ0HVD1VCW4ZASCC', 'T-425', '2026-06-14 18:14:36', '2026-06-14 18:14:36', NULL, 'b09fc55465f7de02cf98f69c99e0e6e3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCEP60AS6AF654SWA189A5ZR', 'T-426', '2026-06-14 18:15:42', '2026-06-14 18:15:42', NULL, '91f50c6e38332047f8619db428d4b376', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCEP642C8ZZ1T20RXQQ3143M', 'T-427', '2026-06-14 18:15:43', '2026-06-14 18:15:43', NULL, '55a937def177025ef6b61a222d88b142', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCEP67ZHMBFW0GRH9JKDMQ7R', 'T-428', '2026-06-14 18:15:44', '2026-06-14 18:15:44', NULL, '185e7d3ce8529fbe1f4543f4c635f200', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCEP6BDBHGMK9VCRV6JQ00TW', 'T-429', '2026-06-14 18:15:45', '2026-06-14 18:15:45', NULL, 'ef268614a716384a7597b3e304a6c176', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCEP6EVN9S35T02MHA2AS7YW', 'T-430', '2026-06-14 18:15:46', '2026-06-14 18:15:46', NULL, 'd6333df4da5b7ab8958149a9f0d17974', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCGJ30V24BJB001GZCR5QKTC', 'T-431', '2026-06-14 22:37:27', '2026-06-14 22:37:27', NULL, 'b886820e87f5abd329126bf5e9f1a3da', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCM9ER04JVFW8CN3JW1AWYA8', 'T-432', '2026-06-15 07:18:58', '2026-06-15 07:18:58', NULL, '71f3e4c95f66abc5e7e5820548201e41', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCM9F446MZFXVHH65Q6CKTPM', 'T-433', '2026-06-15 07:19:01', '2026-06-15 07:19:01', NULL, 'b9a361f2c29b286bc808dbea57a05a7e', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCM9FHC8VX50759X35VNER1R', 'T-434', '2026-06-15 07:19:04', '2026-06-15 07:19:04', NULL, '403c4c8aa5659bb379cb8add9dff800b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCM9FYDEXCM15FXTER032K84', 'T-435', '2026-06-15 07:19:08', '2026-06-15 07:19:08', NULL, '7c2ed604aecea99b742b341166cf2257', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCM9GAQ2G0KCVMZS67SK3324', 'T-436', '2026-06-15 07:19:11', '2026-06-15 07:19:11', NULL, '3114ab57de9b03aa1e745af01001eee1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCNYXXH5AAHZR7WV0550J3RC', 'T-437', '2026-06-15 11:12:36', '2026-06-15 11:12:36', NULL, '74dd08c8c42f556959746ee1a47561e6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQ8HB61N3TWVJ8YSMHH2TJ4', 'T-438', '2026-06-15 14:14:23', '2026-06-15 14:14:23', NULL, 'fa072ae8dd819784440bb44b5fe689d8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQHWQ40AY6SNVRJ86YWA0J8', 'T-439', '2026-06-15 14:55:15', '2026-06-15 14:55:15', NULL, '2427484ebb324d731cb8e099a2ad04ab', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQZ47MAN835B215GSSMRV8W', 'T-440', '2026-06-15 15:53:05', '2026-06-15 15:53:05', NULL, 'f219bb1a70eb1f49e30975ce8c526051', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCZDVPBWGM5NHJ9BNQBVKCD0', 'T-441', '2026-06-16 09:16:07', '2026-06-16 09:16:07', NULL, 'fbabc4fc344b34476b38a186c2f44a16', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCZGG38FF8T9ADF945Z0XPMG', 'T-442', '2026-06-16 09:27:39', '2026-06-16 09:27:39', NULL, 'c85d8fd95cd73aec1e83b477612e1131', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCRERT7X5WMZSGKQCA6T0VB4', 'T-440', '2026-06-15 17:01:25', '2026-06-15 17:01:25', NULL, 'b8e152bf87ec8d81d1bddeb023f37883', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQZ47MAN835B215GSSMRV8W', 'T-443', '2026-06-15 15:53:05', '2026-06-16 10:17:57', NULL, 'a4d4390596d24d7dc28d80861e36d66b', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD07ECS3GK2V7Z2WYYPJHJYC', 'T-444', '2026-06-16 11:07:54', '2026-06-16 11:07:54', NULL, 'ec7a0d8d01c984d931855a6e5c4e86ec', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09C4A0HPZSP8HP44F7A894', 'T-445', '2026-06-16 11:16:20', '2026-06-16 11:16:20', NULL, '418d561d50d37c3dd9b6e3abe5fc1b1f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09DH88J1659FDDYJ83JH1M', 'T-446', '2026-06-16 11:16:31', '2026-06-16 11:16:31', NULL, '7c0bc42be1a170b5bb2dd8bd7b027d69', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09SHDMGT66C4D1DRZQZ7RR', 'T-447', '2026-06-16 11:18:10', '2026-06-16 11:18:10', NULL, '203dfb0348a94392f2d087b79aee655f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09TVT3E3ZSV09QRNTSQ8J4', 'T-448', '2026-06-16 11:18:20', '2026-06-16 11:18:20', NULL, '765a91fb5b51889861a41f7eea308ea6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09WB2XSRP0AZ204FDP681M', 'T-449', '2026-06-16 11:18:32', '2026-06-16 11:18:32', NULL, '1dbd17ff345551d3f091a226bb0f7164', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD09XWEXRJ4JS8MFPQGJEY5M', 'T-450', '2026-06-16 11:18:45', '2026-06-16 11:18:45', NULL, '56f97ccefa83681c387ee9cc4ca6a477', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0A0ZTS9JZCSQ4W8ZVEH2VR', 'T-451', '2026-06-16 11:19:11', '2026-06-16 11:19:11', NULL, 'c329f6f1a5d205b7bdf5ab682812a6d1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0A4MY8DF6NB0KNV96RQADR', 'T-452', '2026-06-16 11:19:41', '2026-06-16 11:19:41', NULL, '71a7729a8cf7ebc4e915a9e2736717bd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0A6K9B60ADTFBZA6NBVJFM', 'T-453', '2026-06-16 11:19:57', '2026-06-16 11:19:57', NULL, 'd408d563785166ee1b40e7494c7f3bbc', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0ABC7QNEC3XCTV73YPSGR4', 'T-454', '2026-06-16 11:20:36', '2026-06-16 11:20:36', NULL, '27e2ae5b0897eb0f589f4617061101a9', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD15S1A0WRTY9WWFG0R4AAZ4', 'T-455', '2026-06-16 13:20:25', '2026-06-16 13:20:25', NULL, '370e913c62eab739cf39bda08089e033', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD15TY946689VZK3MNABSMDW', 'T-456', '2026-06-16 13:20:41', '2026-06-16 13:20:41', NULL, '6041202d66dd93ee3d22206ece3a7db7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD15W7SBVAD3QR5NVE67PKWR', 'T-457', '2026-06-16 13:20:52', '2026-06-16 13:20:52', NULL, 'c9bef415fb7d9d03444fde53ecac3bb1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD1HK7YKJTEK1WV4VHK0RT8R', 'T-458', '2026-06-16 14:12:04.212', '2026-06-16 14:12:04.212', NULL, '070f1def635ee013df639cb9fe81e357', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD1JBRABJHX804CPMZJDC444', 'T-459', '2026-06-16 14:15:25.011', '2026-06-16 14:15:25.011', NULL, '44d5db70ef13ead00c4dcc437c387cec', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91A7VEW3VCY7QX1END2Z3G', 'T-460', '2026-06-17 07:39:25.019', '2026-06-17 07:39:25.019', NULL, 'e7e749d35dc413a560d3347be5f4a9ee', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD91RWDWZPHFPJ72FHHHWS08', 'T-461', '2026-06-17 07:41:24.975', '2026-06-17 07:41:24.975', NULL, '4e3fba7aaad762b7b7cd854459cf664a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0TPYSWEM10RP0Q76XAP58', 'T-462', '2026-06-17 09:57:06.422', '2026-06-17 09:57:06.422', NULL, '4be5f7eb00ca81eb07015af05ed144d3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0VPB99NGS4J6Z5B2RJM2M', 'T-463', '2026-06-17 09:57:14.458', '2026-06-17 09:57:14.458', NULL, 'd5d02453175411c13d21361b084494bd', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0WCPG458GF5FXTXM9VY98', 'T-464', '2026-06-17 09:57:20.180', '2026-06-17 09:57:20.180', NULL, 'c787ef61befc6698286ebdaf613e2a41', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0X5WFME83GS0DKYG3WVJ8', 'T-465', '2026-06-17 09:57:26.627', '2026-06-17 09:57:26.627', NULL, '116b1a377950dfcef4e5b6db90141faa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0XMA9BQV4RHJ55BFN4JR4', 'T-466', '2026-06-17 09:57:30.322', '2026-06-17 09:57:30.322', NULL, 'd25bc26eb29445fc35cf53f3d54049e5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YCY2WGSG8W46RHQ5Z9MW', 'T-467', '2026-06-17 09:57:36.624', '2026-06-17 09:57:36.624', NULL, 'a47c675ca67b86ca3c8d4c1a8acc5b80', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA0YYCJ0NK8C4HMDYKJHRDG', 'T-468', '2026-06-17 09:57:41.092', '2026-06-17 09:57:41.092', NULL, 'b988d9578b1ca079c040f07265a008b4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDA10DRQE3SED10JAW2CZDCR', 'T-469', '2026-06-17 09:57:53.221', '2026-06-17 09:57:53.221', NULL, '2a72e3e647afc1b5b235ab1a97d298f8', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDB1VFADV4QK1YG29T658T8C', 'T-470', '2026-06-17 12:21:23.411', '2026-06-17 12:21:23.411', NULL, '0f95e5a1faa7a7e902c765f449cceb15', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDDJ17C3GZWNE98NRVXP189C', 'T-471', '2026-06-17 18:11:42.049', '2026-06-17 18:11:42.049', NULL, '10a9a957d647a63ce69dc4b6b564f6aa', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDDTCGG5Z0KNQKF89W1VZSQ8', 'T-472', '2026-06-17 18:48:11.649', '2026-06-17 18:48:11.649', NULL, '097120cff851cb2dac9f54937f4c7b17', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDDX5GVH3FTCVDEC1QAFACY4', 'T-473', '2026-06-17 19:00:20.828', '2026-06-17 19:00:20.828', NULL, '647782edc3fbb4e7285e4f82a1fb84be', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDDX5KEAJ8KRWVV7ZSG6H7A0', 'T-474', '2026-06-17 19:00:21.490', '2026-06-17 19:00:21.490', NULL, '79576f18553ed885d3a2b745becdf2f5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDEMY3DQWDNY535PMMSB0CSW', 'T-475', '2026-06-17 20:44:11.501', '2026-06-17 20:44:11.501', NULL, 'bb2b56ea9a76d967123238f588c70aba', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FDXN3ZBRS6JK7Q8G6JVSPXFC', 'T-476', '2026-06-19 07:42:08.735', '2026-06-19 07:42:08.735', NULL, 'f75a0a8c00b0ec40c110c1169e42fe2c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FEWB9JA5CMTXB5D7G1NSHAV4', 'T-477', '2026-06-22 07:13:19.958', '2026-06-22 07:13:19.958', NULL, '0314d96a690bdadc122ce0a1e9ed0f5c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFKFYBZFKBX0WV574QJEH2BC', 'T-478', '2026-06-24 13:09:16.923', '2026-06-24 13:09:16.923', NULL, 'f1ea48c2cfa08915841d99eea06a9974', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', 'T-477', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, '64605163f24e3846463f3afb4ed62fd1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W3V175EM4F8ZHC6JFM4', 'T-478', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, '1c2e59e6220c0b288103c4a71a8282ca', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W6GP535GR8XD1XEHYWG', 'T-479', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, '2a6162f26c4c0b6e7bceb1f1a2ffe167', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W95HJK08BCRQSWFZBF4', 'T-480', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, '8a42c8c1fc2036d6ea73521266e87235', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49WBTT3ESK6QG0XZ1VN2G', 'T-481', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, 'd1d616d020e6ea8661c1f5553e3001eb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49WEE5N4PESF5G1G5JRHR', 'T-482', '2026-06-25 09:16:42', '2026-06-25 09:16:42', NULL, '557f92392db9b5c1e6b6840fe1293b7d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49VYMPF18PYQXD9PCMHN8', 'T-483', '2026-06-25 09:16:42', '2026-06-26 21:35:04.076', NULL, '2841b381bbb03e6a9cdb970280cd2207', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FFW49W3V175EM4F8ZHC6JFM4', 'T-484', '2026-06-25 09:16:42', '2026-06-26 21:35:07.645', NULL, 'd90df1d5e2da44e81f60edb8c5fb2823', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGN13H42TP2MP3T27CTSCDRW', 'T-485', '2026-06-27 19:17:59.713', '2026-06-27 19:17:59.713', NULL, 'b345ba60d55cfdbc7c2e9bb9187ee171', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGPG4WNNH3BWDRVZXYQTW7Z0', 'T-486', '2026-06-27 22:43:31.629', '2026-06-27 22:43:31.629', NULL, 'cd344c35e0eca5673be26790aa8d292c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQ789MDB00EQAXTXBVJDXM', 'T-487', '2026-06-28 06:13:51.821', '2026-06-28 06:13:51.821', NULL, '184f63035c0a014dc4fb863e512f8779', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQ8B7WDKZ174GJDGWW0GS0', 'T-488', '2026-06-28 06:14:00.768', '2026-06-28 06:14:00.768', NULL, '69e3283ee3c10bcd2ca5b5cbad6a8b1f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQ8YSZA5YNP1JE8SJHXWBG', 'T-489', '2026-06-28 06:14:05.776', '2026-06-28 06:14:05.776', NULL, '0b37f24529eb3bb4f2b295dda3bb04ea', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGSQP1YPG70RPQJ4XZDH2T1M', 'T-490', '2026-06-28 06:15:53.077', '2026-06-28 06:15:53.077', NULL, '586b7d8495ad019b436fddbf973c9e63', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGVCY4M0ZK72HZT2FSZF968W', 'T-491', '2026-06-28 10:08:32.933', '2026-06-28 10:08:32.933', NULL, '3895f296d80984ccd613ca9853a05eda', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGVDBD0F14FV5CDJQB063YSR', 'T-492', '2026-06-28 10:10:21.572', '2026-06-28 10:10:21.572', NULL, '341150811f14eb3f4486067ffb1197c4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGVNCZS0JZP5Y7596GBV4RFC', 'T-493', '2026-06-28 10:45:31.721', '2026-06-28 10:45:31.721', NULL, 'eec40f4714242cf343035481684f2aba', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGX26B0NAC9WRJMVB0QE6CV8', 'T-494', '2026-06-28 14:01:13.733', '2026-06-28 14:01:13.733', NULL, '37bf4baec69cb3d06072793cd3d60a46', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYPJ6FTEPP4JK3D7D01ZSMM', 'T-495', '2026-06-28 17:50:02.366', '2026-06-28 17:50:02.366', NULL, '40dbd25d323a8192e8f65a6e1c2dd33d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'T-496', '2026-06-28 18:00:41.420', '2026-06-28 18:00:41.420', NULL, 'd2e472745c710eb00555b2b824d4e214', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZK6PWBRBK9J2XPJ55Y3630', 'T-497', '2026-06-28 19:55:10.439', '2026-06-28 19:55:10.439', NULL, '56f8bf5d0e9a52d9ce3c7a293b5f8972', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKEHPT1TMFMR0KYFGR087W', 'T-498', '2026-06-28 19:56:14.646', '2026-06-28 19:56:14.646', NULL, 'c62ee89f4aa203262fab74da8604777a', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKEHPSSHEG6ZBM0B4DMM6C', 'T-498', '2026-06-28 19:56:14.655', '2026-06-28 19:56:14.655', NULL, '1a47f2a97f13a7565080893758424fec', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKEHPW9GMXNACA38MK56HR', 'T-498', '2026-06-28 19:56:14.655', '2026-06-28 19:56:14.655', NULL, '2c606da2b11071cee3bfcee4855d4e66', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW1721NKWY6XZG3KYB8', 'T-499', '2026-06-28 19:56:47.968', '2026-06-28 19:56:47.968', NULL, '135e7af3ddf32a676fcfadd150061dd6', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW6EDH8TR45M86EWB5M', 'T-499', '2026-06-28 19:56:47.977', '2026-06-28 19:56:47.977', NULL, 'fc370ccee9cd94d0de9988f08963b8f1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW9P697RTQ68R3NKBR8', 'T-499', '2026-06-28 19:56:47.978', '2026-06-28 19:56:47.978', NULL, '99eb5554507cf5b29a158838f156d544', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKEHPW9GMXNACA38MK56HR', 'T-500', '2026-06-28 19:56:14.655', '2026-06-28 19:57:02.538', NULL, '6b529f95abd005b73e20b293dcba765c', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKEHPT1TMFMR0KYFGR087W', 'T-501', '2026-06-28 19:56:14.646', '2026-06-28 19:57:25.895', NULL, '4e1059be29e69c094168bb55e06704a4', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW1721NKWY6XZG3KYB8', 'T-502', '2026-06-28 19:56:47.968', '2026-06-28 19:57:25.904', NULL, '2c08cf1dfc5c7ba16f756db7c80bc300', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW6EDH8TR45M86EWB5M', 'T-503', '2026-06-28 19:56:47.977', '2026-06-28 19:57:25.905', NULL, '5177977a9215f17efa101e50b03ad8eb', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGZKJKW9P697RTQ68R3NKBR8', 'T-504', '2026-06-28 19:56:47.978', '2026-06-28 19:57:25.906', NULL, 'cb7f70a279326ff6e29a8c7bdeb78c0f', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FH621XBYJBGE1XPSFFK4YZGM', 'T-505', '2026-06-29 10:58:54.943', '2026-06-29 10:58:54.943', NULL, 'b402cc72b921d446a6e4f6c759d72d54', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FHAX7FV5KWGZQ31617R63W94', 'T-506', '2026-06-29 22:16:52.953', '2026-06-29 22:16:52.953', NULL, 'fdeccc75d6a70fae57de814d11695473', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D0GAXM1FN42PJKG7FE34G', 'T-507', '2026-07-02 09:41:05.241', '2026-07-02 09:41:05.241', NULL, 'd9dec9b9ed45db65467318f53eb05157', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D1M6ESSSQ1ZERTH4V9YN4', 'T-508', '2026-07-02 09:41:14.425', '2026-07-02 09:41:14.425', NULL, '5389a964251dc22408c41ceac6954f4d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'T-509', '2026-07-02 20:31:02.783', '2026-07-02 20:31:02.783', NULL, 'ea835aca1960e1bee3d0710be19b8bba', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'T-510', '2026-07-05 09:52:40.384', '2026-07-05 09:52:40.384', NULL, '6acffc225f49858f782c8c5e801e1c24', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'T-511', '2026-07-13 15:17:10.276', '2026-07-13 15:17:10.276', NULL, 'ffc35cbc7ffe3577e9f103ce6b411857', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
|
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTF7KE5Y497PQC7SCFGR1KC', 'T-512', '2026-07-13 20:48:23.414', '2026-07-13 20:48:23.414', NULL, '90218f8881c60ea87ee29cdfc4e4bdb3', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
-- Auto-generated by pql init. CREATE TABLE statements
|
-- Auto-generated by migrate-ids (D-26). CREATE TABLE statements
|
||||||
-- for the planning schema; per-table dir keeps the changelog
|
-- for the planning schema; per-table dir keeps the changelog
|
||||||
-- self-describing per D-15. CREATE TABLE IF NOT EXISTS is
|
-- self-describing per D-15.
|
||||||
-- idempotent so running schema files from each directory in
|
-- pql:created_by: migrate-ids
|
||||||
-- replay order is harmless.
|
-- pql:canonical_version: 2
|
||||||
--
|
|
||||||
-- Importer parses the markers below to detect schema drift
|
|
||||||
-- between the producing pql version and the local one — a
|
|
||||||
-- bumped canonical_version means projection rules changed
|
|
||||||
-- and replay must refuse rather than silently corrupt state.
|
|
||||||
-- pql:created_by: 1.4.26
|
|
||||||
-- pql:canonical_version: 1
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS decisions (
|
CREATE TABLE IF NOT EXISTS decisions (
|
||||||
@@ -43,14 +36,23 @@ CREATE TABLE IF NOT EXISTS decision_refs (
|
|||||||
PRIMARY KEY (source_id, target_id, ref_type)
|
PRIMARY KEY (source_id, target_id, ref_type)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Identity split (D-26): a ticket's stable, collision-proof identity is its
|
||||||
|
-- record_id (a locally-generated ULID, planning.NewRecordID); the friendly
|
||||||
|
-- T-NNN label lives in ticket_idmap and may be reconciled. Every structural
|
||||||
|
-- reference (parent, deps, history, labels) targets record_id, so a label
|
||||||
|
-- clash never corrupts the graph — only ticket_idmap needs a relabel.
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
id TEXT PRIMARY KEY,
|
record_id TEXT PRIMARY KEY,
|
||||||
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
||||||
parent_id TEXT REFERENCES tickets(id),
|
parent_record_id TEXT REFERENCES tickets(record_id),
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'backlog'
|
-- No CHECK enumeration: the ticket status vocabulary is per-vault
|
||||||
CHECK(status IN ('backlog','ready','in_progress','review','done','cancelled')),
|
-- configurable (ticket_statuses in .pql/config.yaml). Validation lives
|
||||||
|
-- in Go (planning.StatusSet), so adding/renaming statuses needs no
|
||||||
|
-- schema change. The DEFAULT is a harmless fallback — CreateTicket
|
||||||
|
-- always inserts the configured default explicitly.
|
||||||
|
status TEXT NOT NULL DEFAULT 'backlog',
|
||||||
priority TEXT DEFAULT 'medium'
|
priority TEXT DEFAULT 'medium'
|
||||||
CHECK(priority IN ('critical','high','medium','low')),
|
CHECK(priority IN ('critical','high','medium','low')),
|
||||||
assigned_to TEXT,
|
assigned_to TEXT,
|
||||||
@@ -63,19 +65,33 @@ CREATE TABLE IF NOT EXISTS tickets (
|
|||||||
canonical_version INTEGER
|
canonical_version INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- ticket_idmap maps a record_id to its current friendly label (T-NNN).
|
||||||
|
-- ticket_id is intentionally NOT globally unique: two uncoordinated clones
|
||||||
|
-- can mint the same label, which surfaces as a duplicate-label collision
|
||||||
|
-- (detected at replay) and is fixed with "pql ticket relabel".
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_idmap (
|
||||||
|
record_id TEXT PRIMARY KEY REFERENCES tickets(record_id),
|
||||||
|
ticket_id TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_deps (
|
CREATE TABLE IF NOT EXISTS ticket_deps (
|
||||||
blocker_id TEXT NOT NULL REFERENCES tickets(id),
|
blocker_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
blocked_id TEXT NOT NULL REFERENCES tickets(id),
|
blocked_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (blocker_id, blocked_id)
|
PRIMARY KEY (blocker_record_id, blocked_record_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_history (
|
CREATE TABLE IF NOT EXISTS ticket_history (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
field TEXT NOT NULL,
|
field TEXT NOT NULL,
|
||||||
old_value TEXT,
|
old_value TEXT,
|
||||||
new_value TEXT,
|
new_value TEXT,
|
||||||
@@ -89,14 +105,14 @@ CREATE TABLE IF NOT EXISTS ticket_history (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_labels (
|
CREATE TABLE IF NOT EXISTS ticket_labels (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
label TEXT NOT NULL,
|
label TEXT NOT NULL,
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (ticket_id, label)
|
PRIMARY KEY (ticket_record_id, label)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS meta (
|
CREATE TABLE IF NOT EXISTS meta (
|
||||||
@@ -109,6 +125,8 @@ CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
|||||||
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_record_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ticket_idmap_label ON ticket_idmap(ticket_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG3T4A7CYPTG535KVAVH6C', 'multi-window', '2026-06-14 15:29:27', '2026-06-14 15:29:27', NULL, 'ce03f8eb534bc45e2c1c12e9b30a2c30', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCDG3T4A7CYPTG535KVAVH6C', 'ipc', '2026-06-14 15:29:28', '2026-06-14 15:29:28', NULL, 'e6789b66db5c1de85daf6fc8d3474449', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCNYXXH5AAHZR7WV0550J3RC', 'regression', '2026-06-15 11:12:41', '2026-06-15 11:12:41', NULL, 'd1aee45df369a9afed1ecc7bc6043255', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCNYXXH5AAHZR7WV0550J3RC', 'claude-cli', '2026-06-15 11:12:41', '2026-06-15 11:12:41', NULL, '2d486f878edbd7a898ece18900e0d9d6', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQ8HB61N3TWVJ8YSMHH2TJ4', 'web', '2026-06-15 14:22:06', '2026-06-15 14:22:06', NULL, '6867c9766259a7f09e81ff515973914e', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQHWQ40AY6SNVRJ86YWA0J8', 'path', '2026-06-15 15:24:11', '2026-06-15 15:24:11', NULL, 'e73b3b85732a2c21be23353a0f7f1493', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQHWQ40AY6SNVRJ86YWA0J8', 'web', '2026-06-15 15:24:11', '2026-06-15 15:24:11', NULL, '8c93337891e74d67d2465ba2c3b901d5', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
|
INSERT INTO ticket_labels (ticket_record_id, label, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FCQZ47MAN835B215GSSMRV8W', 'web', '2026-06-15 15:53:35', '2026-06-15 15:53:35', NULL, '4cbf5007b12087b88b8acb36f3616bf8', 2) ON CONFLICT(ticket_record_id, label) DO UPDATE SET updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_labels.updated_at;
|
||||||
@@ -1,15 +1,8 @@
|
|||||||
-- Auto-generated by pql init. CREATE TABLE statements
|
-- Auto-generated by migrate-ids (D-26). CREATE TABLE statements
|
||||||
-- for the planning schema; per-table dir keeps the changelog
|
-- for the planning schema; per-table dir keeps the changelog
|
||||||
-- self-describing per D-15. CREATE TABLE IF NOT EXISTS is
|
-- self-describing per D-15.
|
||||||
-- idempotent so running schema files from each directory in
|
-- pql:created_by: migrate-ids
|
||||||
-- replay order is harmless.
|
-- pql:canonical_version: 2
|
||||||
--
|
|
||||||
-- Importer parses the markers below to detect schema drift
|
|
||||||
-- between the producing pql version and the local one — a
|
|
||||||
-- bumped canonical_version means projection rules changed
|
|
||||||
-- and replay must refuse rather than silently corrupt state.
|
|
||||||
-- pql:created_by: 1.4.26
|
|
||||||
-- pql:canonical_version: 1
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS decisions (
|
CREATE TABLE IF NOT EXISTS decisions (
|
||||||
@@ -43,14 +36,23 @@ CREATE TABLE IF NOT EXISTS decision_refs (
|
|||||||
PRIMARY KEY (source_id, target_id, ref_type)
|
PRIMARY KEY (source_id, target_id, ref_type)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- Identity split (D-26): a ticket's stable, collision-proof identity is its
|
||||||
|
-- record_id (a locally-generated ULID, planning.NewRecordID); the friendly
|
||||||
|
-- T-NNN label lives in ticket_idmap and may be reconciled. Every structural
|
||||||
|
-- reference (parent, deps, history, labels) targets record_id, so a label
|
||||||
|
-- clash never corrupts the graph — only ticket_idmap needs a relabel.
|
||||||
CREATE TABLE IF NOT EXISTS tickets (
|
CREATE TABLE IF NOT EXISTS tickets (
|
||||||
id TEXT PRIMARY KEY,
|
record_id TEXT PRIMARY KEY,
|
||||||
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
type TEXT NOT NULL CHECK(type IN ('initiative','epic','story','task','bug')),
|
||||||
parent_id TEXT REFERENCES tickets(id),
|
parent_record_id TEXT REFERENCES tickets(record_id),
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
description TEXT,
|
description TEXT,
|
||||||
status TEXT NOT NULL DEFAULT 'backlog'
|
-- No CHECK enumeration: the ticket status vocabulary is per-vault
|
||||||
CHECK(status IN ('backlog','ready','in_progress','review','done','cancelled')),
|
-- configurable (ticket_statuses in .pql/config.yaml). Validation lives
|
||||||
|
-- in Go (planning.StatusSet), so adding/renaming statuses needs no
|
||||||
|
-- schema change. The DEFAULT is a harmless fallback — CreateTicket
|
||||||
|
-- always inserts the configured default explicitly.
|
||||||
|
status TEXT NOT NULL DEFAULT 'backlog',
|
||||||
priority TEXT DEFAULT 'medium'
|
priority TEXT DEFAULT 'medium'
|
||||||
CHECK(priority IN ('critical','high','medium','low')),
|
CHECK(priority IN ('critical','high','medium','low')),
|
||||||
assigned_to TEXT,
|
assigned_to TEXT,
|
||||||
@@ -63,19 +65,33 @@ CREATE TABLE IF NOT EXISTS tickets (
|
|||||||
canonical_version INTEGER
|
canonical_version INTEGER
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- ticket_idmap maps a record_id to its current friendly label (T-NNN).
|
||||||
|
-- ticket_id is intentionally NOT globally unique: two uncoordinated clones
|
||||||
|
-- can mint the same label, which surfaces as a duplicate-label collision
|
||||||
|
-- (detected at replay) and is fixed with "pql ticket relabel".
|
||||||
|
CREATE TABLE IF NOT EXISTS ticket_idmap (
|
||||||
|
record_id TEXT PRIMARY KEY REFERENCES tickets(record_id),
|
||||||
|
ticket_id TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
|
deleted_at TEXT,
|
||||||
|
hash TEXT,
|
||||||
|
canonical_version INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_deps (
|
CREATE TABLE IF NOT EXISTS ticket_deps (
|
||||||
blocker_id TEXT NOT NULL REFERENCES tickets(id),
|
blocker_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
blocked_id TEXT NOT NULL REFERENCES tickets(id),
|
blocked_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (blocker_id, blocked_id)
|
PRIMARY KEY (blocker_record_id, blocked_record_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_history (
|
CREATE TABLE IF NOT EXISTS ticket_history (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
field TEXT NOT NULL,
|
field TEXT NOT NULL,
|
||||||
old_value TEXT,
|
old_value TEXT,
|
||||||
new_value TEXT,
|
new_value TEXT,
|
||||||
@@ -89,14 +105,14 @@ CREATE TABLE IF NOT EXISTS ticket_history (
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS ticket_labels (
|
CREATE TABLE IF NOT EXISTS ticket_labels (
|
||||||
ticket_id TEXT NOT NULL REFERENCES tickets(id),
|
ticket_record_id TEXT NOT NULL REFERENCES tickets(record_id),
|
||||||
label TEXT NOT NULL,
|
label TEXT NOT NULL,
|
||||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||||
deleted_at TEXT,
|
deleted_at TEXT,
|
||||||
hash TEXT,
|
hash TEXT,
|
||||||
canonical_version INTEGER,
|
canonical_version INTEGER,
|
||||||
PRIMARY KEY (ticket_id, label)
|
PRIMARY KEY (ticket_record_id, label)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS meta (
|
CREATE TABLE IF NOT EXISTS meta (
|
||||||
@@ -109,6 +125,8 @@ CREATE INDEX IF NOT EXISTS idx_tickets_status ON tickets(status);
|
|||||||
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
CREATE INDEX IF NOT EXISTS idx_tickets_team ON tickets(team);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
CREATE INDEX IF NOT EXISTS idx_tickets_decision_ref ON tickets(decision_ref);
|
||||||
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
CREATE INDEX IF NOT EXISTS idx_tickets_assigned ON tickets(assigned_to);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_tickets_parent ON tickets(parent_record_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_ticket_idmap_label ON ticket_idmap(ticket_id);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
CREATE INDEX IF NOT EXISTS idx_decisions_type ON decisions(type);
|
||||||
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
CREATE INDEX IF NOT EXISTS idx_decision_refs_target ON decision_refs(target_id);
|
||||||
|
|||||||
+800
-1564
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,101 @@
|
|||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 graph view (builtin.graph)', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:23', '2026-07-02 06:35:03.555', NULL, 'a46ad64b03bc1b4126e9882ed7b81a3a', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 graph view (builtin.graph)', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:23', '2026-07-02 08:33:27.518', NULL, 'dc254ed9b53362c45d11ac23f600b57d', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D0GAXM1FN42PJKG7FE34G', 'task', NULL, 'Skill cleanup: apply 2026-07-02 estate-review fixes to clide repo + user scope', 'Apply verified findings from the estate-wide skill review: delete commit/penpot-login/clean-house(project copy) skills; centralize d2-diagram/frame0-wireframe/skill-create to user scope de-contaminated; repoint whats-next (governance/, gh, dead links, step 3a); fix git-commit heredoc guidance + stale sidecar/ADR refs; fix clide skill dock slot + description trim; testmode terminal category; ui-design phosphor glyph reference post-T-314; rewrite skills README index.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 09:41:05.239', '2026-07-02 09:41:05.239', NULL, 'c5ddebbb4ffe8611329732087dd1cebb', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D1M6ESSSQ1ZERTH4V9YN4', 'task', NULL, 'Distribute the clide skill per-workspace with an install marker', 'Estate review 2026-07-02: the clide skill is repo-agnostic and hand-copied into other repos (settled-reach), drifting. Long-term story: clide installs the skill into each workspace''s .claude/skills/ with a .pql-install.json-style marker (version + sha256) so staleness is detectable, following pql''s clean-house precedent. Until then the canonical copy lives in the clide repo.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 09:41:14.420', '2026-07-02 09:41:14.420', NULL, '698b529e4ea8e4417ddb3b9846b30c13', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D0GAXM1FN42PJKG7FE34G', 'task', NULL, 'Skill cleanup: apply 2026-07-02 estate-review fixes to clide repo + user scope', 'Apply verified findings from the estate-wide skill review: delete commit/penpot-login/clean-house(project copy) skills; centralize d2-diagram/frame0-wireframe/skill-create to user scope de-contaminated; repoint whats-next (governance/, gh, dead links, step 3a); fix git-commit heredoc guidance + stale sidecar/ADR refs; fix clide skill dock slot + description trim; testmode terminal category; ui-design phosphor glyph reference post-T-314; rewrite skills README index.', 'done', 'medium', NULL, NULL, NULL, '2026-07-02 09:41:05.239', '2026-07-02 09:55:52.109', NULL, '7470547f02b1269981faefe053aa4ae3', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 graph view (builtin.graph)', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).
|
||||||
|
|
||||||
|
COMPLETE (2026-07-02, session 2). All scope delivered + tested (56 graph tests, make test green, real-boot verified via testmode). Slices this session: GraphController (3b67725b), pane shell (6fae1bc4), extension+i18n registration (a5acb6ac), pan+zoom (e6556401), testmode coverage (46d9b403), filter model (f859173b), filter bar (aabec87d). Final feature: force-directed vault graph in the context panel (graph.view, D-47) — hover-highlight, click-to-open, scroll-zoom, drag-pan, and filters (path glob re-queries pql; depth-from-active local graph; tri-state tag include/exclude). Controller uses pql.meta (outlinks+tags in one call) and strips #heading fragments so heading links connect. NOTE: pql data load is 1 files + N meta calls (sequential); batching is a future optimisation if large vaults feel slow.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:23', '2026-07-02 19:47:37.694', NULL, '6ef9144fd880038d5db1d318925a9afd', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G2KHKT5CJYR0TK1WQGMD0', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 graph view (builtin.graph)', 'Tier-5 graph VIEW, absorbed from the former T-7 into the unified canvas epic (T-317). Force-directed layout of the vault (or a filtered subset): nodes are notes, edges are wikilinks. Hover highlights the connected subgraph; click opens the note in the editor. Filter pane: tag include/exclude, file glob, depth-from-active. pql provides the link data (pql backlinks / pql outlinks); rendering is owned in-app (CustomPaint, own-the-rendering-stack). Lives in its own slot per D-47 (context panel), uses MultitabPane (T-83). DISTINCT from the in-card graph TEMPLATE (T-321): T-321 renders a graph passed into the conversation drawing card; this is the full interactive graph pane over the whole vault. Relates to the core renderer (T-318) but has its own force-directed layout.
|
||||||
|
|
||||||
|
PROGRESS (2026-06-29): force-directed layout SOLVER built + tested (lib/src/graph/force_layout.dart, 6 dart-test cases, commit bcef3a6f) — deterministic Fruchterman-Reingold, Flutter-free. REMAINING (the bulk, multi-session): graph data model from pql backlinks/outlinks over the vault; CustomPaint rendering (nodes+edges); pan/zoom; hover-highlight-subgraph; click-opens-note; filter pane (tag/glob/depth); MultitabPane + context-panel slot (D-47) wiring; widget/golden tests. This is a full interactive Tier-5 pane, a fresh-session undertaking — only its solver core is done.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): the graph rendering + interaction foundation is BUILT + tested (4 slices, all committed). (1) force-directed solver — force_layout.dart (bcef3a6f). (2) link-graph model — vault_graph.dart: VaultGraph.fromOutlinks, neighborhood, edgePairs (084bf842). (3) CustomPaint renderer — graph_painter.dart: edges/nodes/labels, hover-dim, fit transform (6bea1723). (4) interactive GraphView — graph_view.dart: hover-highlight + click-to-open, shared GraphViewport hit-testing (c529703b). The graph is a fully working WIDGET (renders + hover + click). REMAINING = the app-integration phase: pql link-data wiring (pql outlinks over the vault -> the file->outlinks map -> VaultGraph), the pane shell (async load + filter: tag/glob/depth + pan/zoom), and MultitabPane + context-panel slot (D-47) + GraphExtension registration.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, session 2): app-integration phase — 3 slices committed. (1) GraphController (graph_controller.dart, 3b67725b) — pql.files + per-file pql.outlinks over the vault -> VaultGraph; loading/error state; debounced files.changed refresh; 6 tests. (2) GraphPanel shell (graph_panel.dart, 6fae1bc4) — loading/empty/error states + GraphView + click-to-open via editor.open; 5 widget tests. (3) GraphExtension registration (extension.dart + builtin.graph i18n, a5acb6ac) — graph.view context-panel tab (D-47), activates after builtin.pql dep; 4 tests; CHANGELOG entry. The graph is now REACHABLE end-to-end (21 graph tests green). REMAINING (T-323 enrichment): pan/zoom on the view; filter controls (tag include/exclude, glob, depth-from-active).
|
||||||
|
|
||||||
|
COMPLETE (2026-07-02, session 2). All scope delivered + tested (56 graph tests, make test green, real-boot verified via testmode). Slices this session: GraphController (3b67725b), pane shell (6fae1bc4), extension+i18n registration (a5acb6ac), pan+zoom (e6556401), testmode coverage (46d9b403), filter model (f859173b), filter bar (aabec87d). Final feature: force-directed vault graph in the context panel (graph.view, D-47) — hover-highlight, click-to-open, scroll-zoom, drag-pan, and filters (path glob re-queries pql; depth-from-active local graph; tri-state tag include/exclude). Controller uses pql.meta (outlinks+tags in one call) and strips #heading fragments so heading links connect. NOTE: pql data load is 1 files + N meta calls (sequential); batching is a future optimisation if large vaults feel slow.', 'done', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:23', '2026-07-02 19:47:44.357', NULL, '4d534c5ebbc8245ac9cdf1c41ddfca06', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 canvas pane (builtin.canvas)', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:17', '2026-07-02 20:27:03.493', NULL, '163772c5b568c9fb0b69715648555c30', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'Model switch + effort toggle: unclear UI feedback', NULL, 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 20:31:02.783', '2026-07-02 20:31:02.783', NULL, '931821336de8bd9ca5e77cd62f3ca1d3', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'Model switch + effort toggle: unclear UI feedback', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 20:31:02.783', '2026-07-02 20:31:02.806', NULL, 'b4e300bee467ba284a30772cb7a186bb', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 canvas pane (builtin.canvas)', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:17', '2026-07-02 20:35:12.739', NULL, '3e2c84564d3b6cf59f8c8f0e8af1b0b5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'Model switch + effort toggle: unclear UI feedback', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.
|
||||||
|
|
||||||
|
EVIDENCE + ROOT CAUSE (2026-07-02, from a /model screenshot). The confirmation renders as a raw, unstyled line: literally ''<local-command-stdout>Set model to claude-fable-5[1m] (claude-fable-5)</local-command-stdout>'', shown under the ''you'' (user) speaker stripe. Three distinct defects in that one line: (a) the CLI''s <local-command-stdout> wrapper tag is displayed verbatim instead of being unwrapped; (b) an ANSI SGR bold code leaks through as literal ''[1m]'' (a \x1b[1m) — slash-command stdout is not ANSI-stripped; (c) it is attributed to the USER speaker, so a system/command acknowledgement masquerades as something the user typed. ROOT CAUSE: clide has NO handling for local-command-stdout at all (grep in lib/ = zero hits) — the slash-command result falls through and is rendered as plain user prose. ENTRY POINTS for the fix: inbound message parse / role attribution in lib/builtin/claude/src/transcript_reader.dart; existing ANSI-strip refs in transcript_reader.dart + claude_composer.dart. IMPROVE: detect local-command-stdout content, unwrap the tag + strip ANSI, and render it as a distinct, clearly-positioned system/command-acknowledgement (NOT the user stripe) so a /model or /effort change is an unmistakable confirmation. Affects all slash-command stdout (model, effort, etc.), so fix at the render/parse path, not per-command.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 20:31:02.783', '2026-07-02 20:39:06.684', NULL, '8678946b438ae5cbdff677bb73949374', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'bug', '06FB0TNQM5TWC00GW0P3X02HZW', 'Model switch + effort toggle: unclear UI feedback', 'REPORTED (2026-07-02, Jeroen): can''t trust that the model switch and the effort toggle actually took effect when used — the UI feedback + positioning leave it uncertain whether the change applied. INVESTIGATE: what confirmation (if any) fires today when the model or effort is changed, and where it surfaces relative to the control. Likely-related surfaces: the Config tab controls (T-414), /effort ownership (T-412), account/model settings control. IMPROVE: give an unmistakable, well-positioned confirmation that the change landed — e.g. the control reflects the new value immediately (selected state), and/or a brief toast/inline acknowledgement near the control, not somewhere the eye isn''t. Goal: after a switch, the user is certain which model/effort is now active.
|
||||||
|
|
||||||
|
EVIDENCE + ROOT CAUSE (2026-07-02, from a /model screenshot). The confirmation renders as a raw, unstyled line: literally ''<local-command-stdout>Set model to claude-fable-5[1m] (claude-fable-5)</local-command-stdout>'', shown under the ''you'' (user) speaker stripe. Three distinct defects in that one line: (a) the CLI''s <local-command-stdout> wrapper tag is displayed verbatim instead of being unwrapped; (b) an ANSI SGR bold code leaks through as literal ''[1m]'' (a \x1b[1m) — slash-command stdout is not ANSI-stripped; (c) it is attributed to the USER speaker, so a system/command acknowledgement masquerades as something the user typed. ROOT CAUSE: clide has NO handling for local-command-stdout at all (grep in lib/ = zero hits) — the slash-command result falls through and is rendered as plain user prose. ENTRY POINTS for the fix: inbound message parse / role attribution in lib/builtin/claude/src/transcript_reader.dart; existing ANSI-strip refs in transcript_reader.dart + claude_composer.dart. IMPROVE: detect local-command-stdout content, unwrap the tag + strip ANSI, and render it as a distinct, clearly-positioned system/command-acknowledgement (NOT the user stripe) so a /model or /effort change is an unmistakable confirmation. Affects all slash-command stdout (model, effort, etc.), so fix at the render/parse path, not per-command.
|
||||||
|
|
||||||
|
SCOPE (do not narrow): the local-command-stdout rendering defect above is ONE symptom, not the whole ticket. The core problem is that after switching model or effort the user has no reliable, well-placed signal that it took effect — so this stays a broad investigate-and-improve of the switch/toggle trust UX, with the render bug as just the first concrete instance. Other symptoms/questions to investigate (non-exhaustive): does the control itself (Config tab picker / effort control / any menu) visibly update to the NEW active value after a switch, or does it look unchanged? is there ANY acknowledgement at the point of interaction, or only (mangled) output buried in the transcript far from where the user clicked? do model vs effort behave consistently, or differently? can clide''s shown ''active'' value drift from what actually took effect (e.g. a switch that silently no-ops)? is the confirmation positioned where the eye already is? The deliverable is: across all these controls, a consistent and unmistakable ''this is now active'' — fixing the render path is necessary but not sufficient. Enumerate the full symptom set during investigation before designing the fix.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-02 20:31:02.783', '2026-07-02 20:41:13.402', NULL, '9c7b3632bd0846533a1b65cc12b8145a', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 canvas pane (builtin.canvas)', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:17', '2026-07-02 21:22:59.395', NULL, '6ba2a2c1892dbf56c582f83bd9753314', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 canvas pane (builtin.canvas)', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).
|
||||||
|
|
||||||
|
Refinement (2026-07-03, user-confirmed): (1) SLOT: Slots.workspace — diff/editor recipe, center column; coexists with Claude the way diff does (D-47). (2) TABS: real MultitabPane<CanvasDoc> — N .canvas files open as tabs (user explicitly chose over the single-TabContribution graph/diff precedent; needs MultitabController plumbing like Claude sessions). (3) FILE-OPEN ROUTING resolved by inspection: TabContribution.fileGlobs is dead (zero consumers) — do NOT wire it. Add a .canvas branch in lib/kernel/src/file_open.dart openWorkspaceFile() publishing to ''builtin.canvas''/''selection'' (mirror of the .md branch), and D-6 CLI parity via a ''canvas'' entry in the _readers map at lib/src/daemon/ui_command.dart:34 → clide ui open canvas <path> (diff precedent). (4) Fix stale doc header lib/src/canvas/json_canvas.dart:5-7 (claims SVG-lowering; actual architecture paints CanvasDoc directly per the ticket''s DECISION NOTE) in the same pass. (5) Edit phase later needs a mutation path (CanvasView has no onChanged; CanvasDoc is immutable-construction only) — deferred, flagged now.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:17', '2026-07-03 20:20:00.827', NULL, '34eeab12879a55e77e6c9841a442cf27', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB2G1WD1839Z90AQ5C0BHNV4', 'story', '06FHAX7FV5KWGZQ31617R63W94', 'Tier-5 canvas pane (builtin.canvas)', 'Tier-5 canvas PANE, absorbed from the former T-7 into the unified canvas epic (T-317, decision D-91). A full workspace pane that renders .canvas files by CONVERTING them into the drawing-card JSON (per D-91: .canvas is an import format, not a native schema) and painting via the shared canvas renderer (T-318). Scope: nodes (note, text, group, image) + edges + layout state; pan/zoom; node selection, drag, resize; edit affordances (add note from file picker, add text node, draw edge between nodes); persist layout back to the .canvas file on disk. Uses MultitabPane (T-83) for tabs and its own slot per D-47; panels are extension-shaped (D-17). Depends on the core renderer (T-318). NOTE: unlike the conversation drawing card (display-only, D-78), this pane is interactive/editable — it is a pane, not a conversation widget.
|
||||||
|
|
||||||
|
SCOPE NOTE (2026-06-29): currently a 17-line stub. This is a from-scratch interactive Tier-5 pane (parse .canvas -> drawing-card JSON, CustomPaint render, pan/zoom, node select/drag/resize, edit affordances, persist .canvas) — a multi-session feature, NOT template-class work. The drawing-card TEMPLATE half of epic T-317 is now complete (svg/d2/image/icon/compare/graph + stdin).
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02): two foundation slices built + tested (from the 17-line stub). (1) JSONCanvas parser/model — lib/src/canvas/json_canvas.dart (2eb5d0f1): typed CanvasDoc (text/file/link/group nodes + edges with sides/ends/color/label), parse + toJson round-trip, skips unknown/malformed; pure Dart, 8 dart-test cases. (2) CustomPaint renderer — lib/builtin/canvas/src/canvas_painter.dart (035a37a1): CanvasBounds + pan/zoom CanvasViewport, group frames + edges (arrowheads) + node cards; node colours from the file (Obsidian presets/hex, NOT clide tokens per arbitrary-content rule), chrome themed; 7 tests (pixel-probe + viewport + colour). DECISION NOTE: the interactive pane paints the CanvasDoc model directly via CustomPaint (hit-testable, cheap re-paint) rather than re-lowering to SVG each frame — the ticket''s ''convert to drawing-card JSON'' path (D-91 SVG substrate) is for the display-only viewer; an editable pane needs direct model painting. Mirrors the graph pane. REMAINING (multi-session): interactive CanvasView (hit-test nodes + pan/zoom + click-select), pane shell (load .canvas from disk, workspace slot D-47, MultitabPane), CanvasExtension registration + open-.canvas routing, then edit affordances (add node/edge, drag, resize) + persist back to disk.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-02, cont.): third foundation slice landed — interactive CanvasView (lib/builtin/canvas/src/canvas_view.dart, 7700fc7a): hitTestCanvasNode (topmost node under a point; cards beat the group frames behind, via the painter''s own viewport) + scroll-zoom + drag-pan + click-select with a focus ring; 6 tests. The canvas rendering + interaction FOUNDATION is now complete + tested (parser 2eb5d0f1, renderer 035a37a1, view 7700fc7a — 21 canvas tests), mirroring where T-323''s foundation was before its integration phase. NOT yet reachable. REACHABLE-INTEGRATION PHASE (next, fresh session): (a) pane shell — a StatefulWidget that loads a .canvas from disk (files.read/editor.open path), holds the CanvasDoc, embeds CanvasView; (b) CanvasExtension registration as a workspace pane (own slot D-47, MultitabPane T-83); (c) FILE-OPEN ROUTING — how opening a .canvas lands in this pane instead of the text editor: NOTE the TabContribution.fileGlobs field is DECLARED but has ZERO consumers in lib/, so this routing must be built (wire fileGlobs, or have the editor delegate by extension, or a command + workspace tab); (d) i18n + tests. THEN the edit phase: add node/text/edge affordances, node drag + resize, and persist the CanvasDoc back to the .canvas file (encode() already exists).
|
||||||
|
|
||||||
|
Refinement (2026-07-03, user-confirmed): (1) SLOT: Slots.workspace — diff/editor recipe, center column; coexists with Claude the way diff does (D-47). (2) TABS: real MultitabPane<CanvasDoc> — N .canvas files open as tabs (user explicitly chose over the single-TabContribution graph/diff precedent; needs MultitabController plumbing like Claude sessions). (3) FILE-OPEN ROUTING resolved by inspection: TabContribution.fileGlobs is dead (zero consumers) — do NOT wire it. Add a .canvas branch in lib/kernel/src/file_open.dart openWorkspaceFile() publishing to ''builtin.canvas''/''selection'' (mirror of the .md branch), and D-6 CLI parity via a ''canvas'' entry in the _readers map at lib/src/daemon/ui_command.dart:34 → clide ui open canvas <path> (diff precedent). (4) Fix stale doc header lib/src/canvas/json_canvas.dart:5-7 (claims SVG-lowering; actual architecture paints CanvasDoc directly per the ticket''s DECISION NOTE) in the same pass. (5) Edit phase later needs a mutation path (CanvasView has no onChanged; CanvasDoc is immutable-construction only) — deferred, flagged now.
|
||||||
|
|
||||||
|
PROGRESS (2026-07-05): REACHABLE-INTEGRATION PHASE COMPLETE (e2e305de). CanvasExtension is a real workspace pane: app-scoped MultitabController on the extension (diff/T-233 pattern) with real per-document sub-tabs (MultitabPane keepAlive, per refinement decision), CanvasPaneHost + CanvasDocumentTab (files.read -> CanvasDoc.parse -> CanvasView; loading/error states), routing wired (openWorkspaceFile .canvas branch; ui.open ''canvas'' reader so clide ui open canvas <path> works; fileGlobs left dead as decided), en_us+nl_nl catalogs, json_canvas doc header corrected. Tests: extension lifecycle (7), pane-host widget (6), file_open routing (5, new file), ui_command canvas case; testmode extension roster now includes builtin.canvas (26/26 real-boot pass). REMAINING (edit phase, fresh session): node drag + resize, add note/text/edge affordances, persist CanvasDoc back to disk — encode() exists; CanvasView needs an onChanged/mutation path (refinement note item 5).', 'in_progress', 'medium', NULL, NULL, NULL, '2026-06-10 11:17:17', '2026-07-05 07:29:15.447', NULL, '1be84ba4d4357171ef329f39b601f4e1', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'task', '06FB0TNQM5TWC00GW0P3X02HZW', 'Composer bypass reachability: Ctrl/Cmd+Shift+M full cycle + shift-click bypass row', 'User decision (2026-07-05), amending T-226''s refinement wording: the original intent was Ctrl/Cmd+Shift+M cycling the FULL permission-mode list including bypassPermissions, with plain Ctrl/Cmd+M keeping the safe trio (default/acceptEdits/plan). Holding shift IS the explicit opt-in gesture — no separate confirm needed. Likewise the composer mode popup (T-275): the bypass row is currently permanently disabled, pointing at ''the cockpit''s confirmed path'' (T-181 roster shift-click) — but that roster is ghost-fed (T-396, TeamMemberJoined never emitted in production), so bypass is unreachable from the primary session''s UI entirely; a visible-but-unreachable option is worse than none. Scope: (1) claude_status: kFullPermissionCycle + nextPermissionMode(); (2) composer key handler: mod+shift+M -> full cycle, mod+M (no shift) -> safe trio; (3) PermissionModeControl: bypass row enabled behind a shift-click gate (plain click no-ops, menu stays open; shift-click selects + closes), trailing ''shift-click'' hint, semantics + tooltip updated; (4) i18n en+nl; (5) tests. The /permissions picker and roster badge paths are unchanged. Refs T-226, T-275, T-181, T-396.', 'backlog', 'medium', NULL, NULL, NULL, '2026-07-05 09:52:40.379', '2026-07-05 09:52:40.379', NULL, 'ec1eed07c9a69b4edbf3f4ffe671f696', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'task', '06FB0TNQM5TWC00GW0P3X02HZW', 'Composer bypass reachability: Ctrl/Cmd+Shift+M full cycle + shift-click bypass row', 'User decision (2026-07-05), amending T-226''s refinement wording: the original intent was Ctrl/Cmd+Shift+M cycling the FULL permission-mode list including bypassPermissions, with plain Ctrl/Cmd+M keeping the safe trio (default/acceptEdits/plan). Holding shift IS the explicit opt-in gesture — no separate confirm needed. Likewise the composer mode popup (T-275): the bypass row is currently permanently disabled, pointing at ''the cockpit''s confirmed path'' (T-181 roster shift-click) — but that roster is ghost-fed (T-396, TeamMemberJoined never emitted in production), so bypass is unreachable from the primary session''s UI entirely; a visible-but-unreachable option is worse than none. Scope: (1) claude_status: kFullPermissionCycle + nextPermissionMode(); (2) composer key handler: mod+shift+M -> full cycle, mod+M (no shift) -> safe trio; (3) PermissionModeControl: bypass row enabled behind a shift-click gate (plain click no-ops, menu stays open; shift-click selects + closes), trailing ''shift-click'' hint, semantics + tooltip updated; (4) i18n en+nl; (5) tests. The /permissions picker and roster badge paths are unchanged. Refs T-226, T-275, T-181, T-396.', 'in_progress', 'medium', NULL, NULL, NULL, '2026-07-05 09:52:40.379', '2026-07-05 09:52:54.013', NULL, '56204043cd686ca0fcae06db735b72ef', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'task', '06FB0TNQM5TWC00GW0P3X02HZW', 'Composer bypass reachability: Ctrl/Cmd+Shift+M full cycle + shift-click bypass row', 'User decision (2026-07-05), amending T-226''s refinement wording: the original intent was Ctrl/Cmd+Shift+M cycling the FULL permission-mode list including bypassPermissions, with plain Ctrl/Cmd+M keeping the safe trio (default/acceptEdits/plan). Holding shift IS the explicit opt-in gesture — no separate confirm needed. Likewise the composer mode popup (T-275): the bypass row is currently permanently disabled, pointing at ''the cockpit''s confirmed path'' (T-181 roster shift-click) — but that roster is ghost-fed (T-396, TeamMemberJoined never emitted in production), so bypass is unreachable from the primary session''s UI entirely; a visible-but-unreachable option is worse than none. Scope: (1) claude_status: kFullPermissionCycle + nextPermissionMode(); (2) composer key handler: mod+shift+M -> full cycle, mod+M (no shift) -> safe trio; (3) PermissionModeControl: bypass row enabled behind a shift-click gate (plain click no-ops, menu stays open; shift-click selects + closes), trailing ''shift-click'' hint, semantics + tooltip updated; (4) i18n en+nl; (5) tests. The /permissions picker and roster badge paths are unchanged. Refs T-226, T-275, T-181, T-396.', 'done', 'medium', NULL, NULL, NULL, '2026-07-05 09:52:40.379', '2026-07-05 10:54:23.532', NULL, '143695c5eefa42dab2c05edcb06a4427', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'task', NULL, 'Per-workspace PATH preset: settings + CLI (env.path) + spawn injection, worktree-aware (FR-1)', NULL, 'backlog', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 15:17:10.275', NULL, 'eb6abfb644234fe0c73b4785efcdad16', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'task', NULL, 'Per-workspace PATH preset: settings + CLI (env.path) + spawn injection, worktree-aware (FR-1)', NULL, 'in_progress', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 15:17:17.532', NULL, '6e4b7347d0e854ea4c5fe4b394c61412', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'task', NULL, 'Per-workspace PATH preset: settings + CLI (env.path) + spawn injection, worktree-aware (FR-1)', 'Implements D-106 (FR-1 + worktree addendum). Storage: user-scope key app.env.pathPrepend.<fnv1a64Hex(canonicalWorkspaceKey(presetRoot))> in ~/.config/clide/settings.yaml — never committed; presetRootFor() resolves a linked-worktree workspace (gitdir: pointer file, e.g. .worktrees/<name>) to the main repo root so all worktrees share the repo''s preset.
|
||||||
|
|
||||||
|
Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pathForSpawn hook (main.dart wires the preset-aware closure); hosted Claude via agentEnvDelta(prependDirs:) — now exports PATH whenever a preset exists even if clide is already on PATH (previous gap) — threaded orchestrator.pathPresetFor ← claude extension ← ctx.settings. Toolchain/supporter-binary resolution deliberately preset-blind (T-98/D-92 fence).
|
||||||
|
|
||||||
|
CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs.
|
||||||
|
|
||||||
|
.worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', 'in_progress', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 15:39:31.309', NULL, 'c5a978f32c7497e478c471069ed20b7c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'task', NULL, 'Per-workspace PATH preset: settings + CLI (env.path) + spawn injection, worktree-aware (FR-1)', 'Implements D-106 (FR-1 + worktree addendum). Storage: user-scope key app.env.pathPrepend.<fnv1a64Hex(canonicalWorkspaceKey(presetRoot))> in ~/.config/clide/settings.yaml — never committed; presetRootFor() resolves a linked-worktree workspace (gitdir: pointer file, e.g. .worktrees/<name>) to the main repo root so all worktrees share the repo''s preset.
|
||||||
|
|
||||||
|
Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pathForSpawn hook (main.dart wires the preset-aware closure); hosted Claude via agentEnvDelta(prependDirs:) — now exports PATH whenever a preset exists even if clide is already on PATH (previous gap) — threaded orchestrator.pathPresetFor ← claude extension ← ctx.settings. Toolchain/supporter-binary resolution deliberately preset-blind (T-98/D-92 fence).
|
||||||
|
|
||||||
|
CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs.
|
||||||
|
|
||||||
|
.worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', 'done', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 16:48:56.833', NULL, '09c6b262b3c0ecfd2f621d27f2cc5eb2', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTF7KE5Y497PQC7SCFGR1KC', 'task', NULL, 'Lead the clide skill description with clide capabilities + env mechanics (FR-2)', NULL, 'backlog', 'low', NULL, NULL, NULL, '2026-07-13 20:48:23.409', '2026-07-13 20:48:23.409', NULL, '28edb12dfa1f2bf75d108f6cf9465ea5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNTF7KE5Y497PQC7SCFGR1KC', 'task', NULL, 'Lead the clide skill description with clide capabilities + env mechanics (FR-2)', NULL, 'done', 'low', NULL, NULL, NULL, '2026-07-13 20:48:23.409', '2026-07-13 20:49:17.282', NULL, 'b7eaec1d037d1c36cf54fac07b3b2dd4', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
@@ -0,0 +1,350 @@
|
|||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FD0ABC7QNEC3XCTV73YPSGR4', 'task', NULL, 'Plumb in Claude Code''s remote-control feature', 'User report 2026-06-16: Claude Code''s **remote-control** feature (start / monitor / steer a running Claude Code session remotely — e.g. from claude.ai or the mobile app) is **not plumbed into clide**.
|
||||||
|
|
||||||
|
clide hosts the `claude` CLI as a stream-json child (`--session-id` / `--resume`, D-77). For remote control to work through clide, a clide-hosted session needs to be discoverable + steerable by the remote-control surface the same way a terminal-launched `claude` is.
|
||||||
|
|
||||||
|
**Step 1 — characterize (don''t assume the mechanism):** determine exactly what Claude Code exposes for remote control on the running CLI version. Likely touch points:
|
||||||
|
- the `~/.claude/sessions/<pid>.json` live-session registry we characterized in T-437 (PID-keyed: sessionId, cwd, version, kind, entrypoint, status) — is this what the remote-control surface enumerates? clide-spawned sessions DO write an entry (we saw `entrypoint: sdk-cli`). Confirm whether clide''s entry is visible/controllable remotely, or whether `entrypoint: sdk-cli` / headless spawn excludes it.
|
||||||
|
- any flag / capability in the `initialize` stream-json probe (T-411/T-151 cache) advertising remote control.
|
||||||
|
- whether enrollment requires the interactive TUI (and so is suppressed under clide''s stream-json spawn).
|
||||||
|
|
||||||
|
**Step 2 — plumb:** wire clide so a clide-hosted session participates in remote control (register correctly / pass the needed flag), and surface its state in the UI (e.g. an indicator that the session is remote-controllable / being driven remotely). If it conflicts with clide''s session ownership (pane pins a session-id, T-156), document the boundary.
|
||||||
|
|
||||||
|
**Open question:** is the goal (a) clide sessions become remotely controllable from claude.ai/mobile, or (b) clide can act as a remote controller of other sessions? Default read is (a). Confirm with the user before building.
|
||||||
|
|
||||||
|
Related: D-77 (stream-json session model), T-437 (sessions registry characterization), T-156 (clide owns session lifecycle), T-411 (capability probe).
|
||||||
|
|
||||||
|
## Step 1 COMPLETE — mechanism characterized and empirically proven (2026-08-07)
|
||||||
|
|
||||||
|
**Goal confirmed as (a):** clide-hosted sessions become remotely controllable from
|
||||||
|
claude.ai / the mobile app. (b) is not in scope.
|
||||||
|
|
||||||
|
### The mechanism is a control_request, not the sessions registry
|
||||||
|
|
||||||
|
The Step-1 hypothesis (that `~/.claude/sessions/<pid>.json` is what the remote
|
||||||
|
surface enumerates) is **wrong**. That registry is incidental. Remote Control is
|
||||||
|
enabled per-session over the stream-json control channel clide already owns.
|
||||||
|
|
||||||
|
Claude Code 2.1.220 ships two bridge integrations:
|
||||||
|
- `[bridge:repl]` — the interactive TUI path (`--remote-control` flag, `/remote-control`)
|
||||||
|
- `[bridge:sdk]` — a **stream-json/SDK path**, which is the one clide needs
|
||||||
|
|
||||||
|
No interactive session, no extra flag, and no CLI changes are required.
|
||||||
|
|
||||||
|
### Wire contract (verified live)
|
||||||
|
|
||||||
|
```
|
||||||
|
→ {"type":"control_request","request_id":"…",
|
||||||
|
"request":{"subtype":"remote_control","enabled":true,"name":"<session name>"}}
|
||||||
|
|
||||||
|
← {"type":"system","subtype":"bridge_state","state":"ready"}
|
||||||
|
← {"type":"control_response","response":{"subtype":"success","response":{
|
||||||
|
"session_url":"https://claude.ai/code/session_0127…",
|
||||||
|
"connect_url":"https://claude.ai/code?environment=",
|
||||||
|
"environment_id":""}}}
|
||||||
|
← {"type":"system","subtype":"bridge_state","state":"connected"}
|
||||||
|
|
||||||
|
→ {"request":{"subtype":"remote_control","enabled":false}} # clean teardown
|
||||||
|
← {"type":"control_response","response":{"subtype":"success"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
Proven by probe against clide''s exact spawn flags (`stream_json_session.dart:78`).
|
||||||
|
`ready → connected` in ~420ms. Debug log confirms `[bridge:sdk] State change: ready`
|
||||||
|
then `connected`; transport is CCR v2 over SSE, shared with the repl bridge.
|
||||||
|
|
||||||
|
**Surface `session_url`, not `connect_url`.** `connect_url` came back as
|
||||||
|
`https://claude.ai/code?environment=` with an empty `environment_id` — the
|
||||||
|
environment concept is not populated on the bare-SDK path (it appears to be filled
|
||||||
|
in only when the `claude remote-control` daemon owns a registered directory).
|
||||||
|
`session_url` is the complete, live link. Confirm before building a QR affordance.
|
||||||
|
|
||||||
|
### CLI-side callback surface (from binary analysis)
|
||||||
|
|
||||||
|
| Callback | Effect |
|
||||||
|
|---|---|
|
||||||
|
| `onInboundMessage` | remote message injected as a user turn (tagged `bridgeOrigin`, `clientPlatform`, `origin`) |
|
||||||
|
| `onPermissionResponse` | → `injectControlResponse` — the remote can answer permission prompts |
|
||||||
|
| `onInterrupt` | remote cancel of the running turn |
|
||||||
|
| `onSetModel` / `onSetPermissionMode` / `onSetMaxThinkingTokens` | remote session control |
|
||||||
|
| `onStateChange` | emits `system/bridge_state` (`ready`\|`connected`\|`failed` + `detail`) on the normal output stream |
|
||||||
|
|
||||||
|
Plus outbound `writeSdkMessages` forwarding of task/thinking/vcs events.
|
||||||
|
|
||||||
|
### Prompt arbitration — resolved, no clide policy to invent
|
||||||
|
|
||||||
|
Decided model (user, 2026-08-07): **first-to-apply wins, both sides linked by the
|
||||||
|
same `request_id`, loser''s prompt retracts on that link, clear is idempotent.**
|
||||||
|
|
||||||
|
This is already the shipped protocol, and it is symmetric:
|
||||||
|
- `setOnControlRequestSent` forwards the pending request to the remote;
|
||||||
|
`setOnControlRequestResolved` → `sendControlCancelRequest(request_id)` retracts it.
|
||||||
|
- `RemoteSessionManager.handleMessage` handles inbound `control_cancel_request` by
|
||||||
|
looking up `pendingPermissionRequests` / `pendingDialogRequests` and retracting;
|
||||||
|
unknown ids are ignored ("nothing pending, ignoring").
|
||||||
|
- The refusal schema states the rule directly: *"Evict on RESOLUTION (your own
|
||||||
|
response — any choice — or `control_cancel_request` retirement), never on receipt
|
||||||
|
… Eviction is idempotent."*
|
||||||
|
|
||||||
|
**The clide gap:** `stream_json_session.dart` parses `control_request` but has **no
|
||||||
|
`control_cancel_request` handling at all**. If the remote answers first, clide''s
|
||||||
|
prompt widget hangs with no retraction. Since pending prompts are already keyed by
|
||||||
|
`request_id` for `resolvePrompt()` (`:758`), the fix is a delete + UI clear on the
|
||||||
|
same key. NOT YET OBSERVED live — the probe ran no tools, so the retraction path is
|
||||||
|
confirmed by decompile only. Verify during implementation.
|
||||||
|
|
||||||
|
### Step 2 scope (remaining)
|
||||||
|
|
||||||
|
1. `enableRemoteControl({String? name})` / `disableRemoteControl()` on
|
||||||
|
`StreamJsonSession` — shaped exactly like `setModel()` (`:932`): request with
|
||||||
|
`request_id`, pending map, reconcile response into `SessionStatus`.
|
||||||
|
2. Handle `system/bridge_state` in the event switch → connection state.
|
||||||
|
3. **Handle inbound `control_cancel_request` → retract the matching pending
|
||||||
|
`ToolPrompt`.** (The arbitration work above; also correct on its own merits.)
|
||||||
|
4. Two `SessionStatus` fields (`session_url`, bridge state).
|
||||||
|
5. Cockpit affordance: connect link / QR + connected indicator.
|
||||||
|
6. `clide claude remote-control <on|off>` verb for D-6 parity.
|
||||||
|
7. Teardown on pane close; pass clide''s derived pane name as `name` (the CLI
|
||||||
|
already names clide sessions e.g. `clide-18`).
|
||||||
|
|
||||||
|
### Constraints found
|
||||||
|
|
||||||
|
- Requires a logged-in subscription account; bridge is skipped on non-first-party
|
||||||
|
providers (`isFirstPartyProvider` check) — needs a disabled UI state.
|
||||||
|
- Help text for the daemon path notes the workspace trust dialog must have been
|
||||||
|
accepted by running `claude` interactively in the directory once. clide spawns
|
||||||
|
non-interactively where trust is auto-skipped — verify this doesn''t block the bridge.
|
||||||
|
- `remoteControlAtStartup` is a user setting ("Start Remote Control bridge
|
||||||
|
automatically each session") — a zero-code way to A/B the behaviour, and a
|
||||||
|
setting clide should probably respect rather than fight.
|
||||||
|
- Related but out of scope: `isolatePeerMachines` (cross-machine `SendMessage`
|
||||||
|
between peer sessions); `claude remote-control` hidden subcommand (`bridgeMain`)
|
||||||
|
which runs a per-directory daemon with `--spawn same-dir|worktree|session`.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-16 11:20:36', '2026-08-07 12:21:08.809', NULL, 'a420c6a2175901ac10d20685907847a5', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'bug', NULL, 'pre-commit changelog hook leaves ticket_deps/ticket_idmap unstaged', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.', 'backlog', 'medium', NULL, NULL, NULL, '2026-06-28 18:00:41.419', '2026-08-07 12:30:44.880', NULL, 'bb5179427efa3ad0aff9a48164833f57', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'bug', NULL, 'pre-commit hook stages no .pql/changelog files (pql plan export --stage)', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-28 18:00:41.419', '2026-08-07 12:30:59.962', NULL, '29a636f1d7c9de8c57184afd2eaf949f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
|
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FGYS06SDJGZ4W3Z9V9HDEATW', 'bug', NULL, 'pre-commit hook stages no .pql/changelog files (pql plan export --stage)', 'The pre-commit hook re-exports + stages .pql/changelog on commit but only catches the tickets + ticket_history tables — it leaves ticket_deps (blocker edges) and ticket_idmap (new T-NNN <-> record_id mappings) UNSTAGED. Seen repeatedly this session (D-103 re-sequencing blockers; T-495 id mapping), each needing a manual follow-up commit; otherwise the planning state silently doesn''t persist and a later branch switch drops it — exactly the failure the hook exists to prevent. Fix: stage ALL of .pql/changelog/ (git add .pql/changelog/), not just the tables the export rewrote. Repro: pql ticket block X --by Y + create a ticket, commit unrelated files, observe ticket_deps/ticket_idmap still modified afterward.
|
||||||
|
|
||||||
|
## Widened 2026-08-07 — broader than the title, and the root cause is different
|
||||||
|
|
||||||
|
### The scope is wrong: tickets + ticket_history are NOT immune
|
||||||
|
|
||||||
|
This ticket states the hook "only catches the tickets + ticket_history tables."
|
||||||
|
That is not the failure mode. On 2026-08-07 a ticket-only turn (appending Step-1
|
||||||
|
findings to T-454) left **`tickets/2026-08.sql` and `ticket_history/2026-08.sql`
|
||||||
|
untracked and unstaged** — the two tables assumed to work. The commit aborted
|
||||||
|
with "nothing added to commit but untracked files present" and needed an explicit
|
||||||
|
`git add` of both paths.
|
||||||
|
|
||||||
|
So no table is reliably staged. Retitle accordingly.
|
||||||
|
|
||||||
|
### Likely root cause: staging is gated on rows appended, not on file dirtiness
|
||||||
|
|
||||||
|
The pre-commit hook is a one-liner that delegates everything to pql:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# .pql/hooks/pre-commit
|
||||||
|
''/…/pql'' plan export --stage 2>/dev/null || true
|
||||||
|
```
|
||||||
|
|
||||||
|
Its output on the failing commit:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
It **wrote both files and staged neither**. Second invocation (after a manual
|
||||||
|
`git add`) returned `{"files_written":null,"rows_written":0}`.
|
||||||
|
|
||||||
|
Hypothesis: `--stage` only issues the `git add` when it appends rows
|
||||||
|
(`rows_written > 0`). Because ticket mutations already **write through** to
|
||||||
|
`.pql/changelog/` synchronously, by the time the pre-commit hook runs there is
|
||||||
|
nothing left to append — `rows_written` is 0 — so the staging step is skipped even
|
||||||
|
though the file on disk is new/dirty. NOT YET VERIFIED; confirm against pql''s
|
||||||
|
`plan export --stage` implementation.
|
||||||
|
|
||||||
|
This also better explains the originally-reported symptom: `ticket_deps` /
|
||||||
|
`ticket_idmap` aren''t special-cased out, they just tend to be *new month files*
|
||||||
|
or already-written-through, hitting the same skip.
|
||||||
|
|
||||||
|
Contributing factor: new-month rollover. These were the first August files, so
|
||||||
|
they were untracked rather than modified — worth checking whether `--stage`
|
||||||
|
handles untracked paths differently from tracked-but-modified ones.
|
||||||
|
|
||||||
|
### The fix belongs in pql, not clide
|
||||||
|
|
||||||
|
clide''s hook has no logic to fix — it is a single delegating line installed by
|
||||||
|
`pql init`. The change is in pql''s `plan export --stage`: stage every file under
|
||||||
|
`.pql/changelog/` that is dirty or untracked, regardless of `rows_written`.
|
||||||
|
Track/land it in the pql repo; this ticket is the clide-side symptom record.
|
||||||
|
|
||||||
|
The ticket''s proposed workaround (`git add .pql/changelog/` on the whole
|
||||||
|
directory) is still correct and would cover untracked files too.
|
||||||
|
|
||||||
|
### Severity is higher than "medium"
|
||||||
|
|
||||||
|
This is a silent data-loss path, not a nuisance. A turn that only files or edits
|
||||||
|
tickets makes no other commit, so the hook is the sole persistence mechanism; when
|
||||||
|
it silently no-ops, the planning state never lands and a later branch switch drops
|
||||||
|
it. The failure is invisible unless someone reads the hook''s JSON on stderr.
|
||||||
|
Consider raising priority and/or making a failed stage loud rather than
|
||||||
|
`2>/dev/null || true`.
|
||||||
|
|
||||||
|
### Correction (same session): not an untracked-file issue — `--stage` never stages
|
||||||
|
|
||||||
|
The "new-month rollover / untracked path" contributing factor above is **disproved**.
|
||||||
|
Tested directly: with `tickets/2026-08.sql` and `ticket_history/2026-08.sql` already
|
||||||
|
tracked and merely *modified*, a bare `git commit` still aborted with "no changes
|
||||||
|
added to commit". Hook output was identical:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"files_written":["…/ticket_history/2026-08.sql","…/tickets/2026-08.sql"],"rows_written":0}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tracked-modified and untracked-new both fail. The only common factor is
|
||||||
|
`rows_written: 0`.
|
||||||
|
|
||||||
|
**Escalates the diagnosis:** this is not intermittent and not table-specific.
|
||||||
|
Because ticket mutations write through to `.pql/changelog/` synchronously, the
|
||||||
|
pre-commit export always finds zero rows left to append, so `--stage` skips its
|
||||||
|
`git add` on *every* commit. In this repo the hook''s staging step is effectively
|
||||||
|
dead — it has likely never worked, and every ticket change that landed did so
|
||||||
|
because some other file in the commit was staged by hand, or because someone
|
||||||
|
noticed and re-added.
|
||||||
|
|
||||||
|
That reframes the earlier `ticket_deps` / `ticket_idmap` reports: those tables
|
||||||
|
weren''t being singled out, they were just the cases where nothing else in the
|
||||||
|
commit masked the failure.
|
||||||
|
|
||||||
|
**Fix (pql):** `plan export --stage` must stage on file state, not on
|
||||||
|
`rows_written` — `git add` every dirty-or-untracked path under `.pql/changelog/`
|
||||||
|
whenever the directory differs from the index, including when the export was a
|
||||||
|
no-op. Consider also dropping the hook''s `2>/dev/null || true` so a staging
|
||||||
|
failure is visible instead of silent.', 'backlog', 'high', NULL, NULL, NULL, '2026-06-28 18:00:41.419', '2026-08-07 12:31:41.104', NULL, '4839606f6898f3f0f39f5c0cbd3d183d', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
|
||||||
+582
@@ -0,0 +1,582 @@
|
|||||||
|
# AGENTS.md for clide — Mistral Vibe operating as Claude Code peer
|
||||||
|
|
||||||
|
This file configures Mistral Vibe to operate in this repo with the same
|
||||||
|
effectiveness as Claude Code. It distills the CLAUDE.md guardrails and all
|
||||||
|
`.claude/skills/` into Vibe's instruction hierarchy, preserving "Claude punch"
|
||||||
|
in a hybrid workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Identity
|
||||||
|
|
||||||
|
You are operating in **clide** — a Flutter/Dart IDE for Claude Code CLI.
|
||||||
|
Your role: **peer to Claude Code**, not replacement. Maintain Claude's
|
||||||
|
behavioral standards, tool discipline, and architectural rigor.
|
||||||
|
|
||||||
|
**Primary directive:** Never lose "Claude punch" — the combination of
|
||||||
|
strict guardrails, CLI-first interaction, and parity between UI and CLI
|
||||||
|
that defines effective operation in this repo.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Non-Negotiable Guardrails (from CLAUDE.md)
|
||||||
|
|
||||||
|
These are load-bearing. Violating any means the design is wrong, not the rule.
|
||||||
|
|
||||||
|
- **Flutter desktop is the host. No Electron, ever.**
|
||||||
|
- **Single process.** The Flutter app hosts everything in-process: IPC server,
|
||||||
|
subsystem handlers (pane, files, editor, git, pql), extensions.
|
||||||
|
- **CLI-first, not MCP.** Drive via `clide <subsystem> <verb>` Bash commands.
|
||||||
|
- **Dart is the core; pql fills the query gap.** PTY spawning is native Dart FFI
|
||||||
|
(`posix_openpt` + `posix_spawn`). `pql` (Go) handles vault queries.
|
||||||
|
- **Own the rendering stack.** PTY, markdown, graph, canvas — all clide-owned.
|
||||||
|
- **User/Claude parity (D-6).** Every CLI subcommand has a UI affordance,
|
||||||
|
and every UI action has a CLI equivalent.
|
||||||
|
- **pql: wrap, don't duplicate.** Clide wraps pql; never re-implements it.
|
||||||
|
- **Repo-is-the-workspace.** Git repo root is the workspace.
|
||||||
|
- **Decision discipline.** All architectural choices live in
|
||||||
|
`governance/decisions/<domain>.md` as `D-NNN` records. Open questions as
|
||||||
|
`Q-NNN` under `governance/questions/<domain>.md`. Rejected as `R-NNN`.
|
||||||
|
- **No pre-existing excuse.** Solo-dev repo — if `make test` is red, fix it
|
||||||
|
first, then your work. Surface blockers; don't push on top of broken state.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tool Discipline (from CLAUDE.md)
|
||||||
|
|
||||||
|
### Make targets are the entry points
|
||||||
|
|
||||||
|
| Purpose | Command | Never call directly |
|
||||||
|
|---------|---------|---------------------|
|
||||||
|
| Launch app | `make run` | `flutter run` |
|
||||||
|
| Static analysis | `make analyze` | `flutter analyze` |
|
||||||
|
| Format | `make format` | `dart format` |
|
||||||
|
| Fast test suite | `make test` | `flutter test` |
|
||||||
|
| Core subsystem tests | `make test-core` | underlying scripts |
|
||||||
|
| Accessibility tests | `make test-a11y` | underlying scripts |
|
||||||
|
| Integration tests | `make test-integration` | underlying scripts |
|
||||||
|
| Pre-push gate | `make push-check` | `ci/*` scripts |
|
||||||
|
| Setup hooks | `make hooks` | `cp .githooks/* .git/hooks/` |
|
||||||
|
| Clean | `make clean` | `rm -rf build/` |
|
||||||
|
|
||||||
|
### Shell hygiene
|
||||||
|
|
||||||
|
- **Working directory is repo root** — never `cd /path/to/clide` or `git -C`
|
||||||
|
- **One command per invocation** — no `&&`/`;` chaining
|
||||||
|
- Exception: `git commit -F` HEREDOC for multi-line messages
|
||||||
|
- Prefer Read/Edit/Grep tools over `cat`/`sed`/`grep` for file inspection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Git Workflow (from git-commit skill)
|
||||||
|
|
||||||
|
### Commit message format: Conventional Commits 1.0
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <imperative subject> (<T-NNN>)
|
||||||
|
|
||||||
|
Optional body: explain WHY, not WHAT. Wrap at ~72 chars.
|
||||||
|
|
||||||
|
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Type:** `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `chore`
|
||||||
|
- Use `feat`/`fix` for user-visible behavior
|
||||||
|
- Use `chore` for bookkeeping (`chore(plan)` for pql ticket housekeeping)
|
||||||
|
- Append `!` after scope for breaking changes: `feat(ipc)!: ...`
|
||||||
|
|
||||||
|
**Scope:** Optional but preferred — subsystem: `settings`, `vim`, `pty`, `git`, `plan`
|
||||||
|
- Lower-case, no spaces
|
||||||
|
|
||||||
|
**Subject:** ≤ 72 characters INCLUDING prefix. No emojis. No "and".
|
||||||
|
|
||||||
|
**Ticket ref:** Trailing `(T-NNN)` when work has a ticket.
|
||||||
|
|
||||||
|
**Body:** Explain the *why*. The diff shows the *what*. Don't restate it.
|
||||||
|
- Hard cap: **60 words per bullet** for CHANGELOG entries
|
||||||
|
- No multi-paragraph bullets
|
||||||
|
- No sub-headers inside bullets
|
||||||
|
- No probe numbers, latency stats, or %-coverage deltas
|
||||||
|
|
||||||
|
### Logically-separated commits
|
||||||
|
|
||||||
|
1. **Read `git status` + `git diff` first** — never stage blind
|
||||||
|
2. **Group by concern, not location:**
|
||||||
|
- Bookkeeping: `.gitignore`, lockfiles, config
|
||||||
|
- Documentation: `README.md`, ADRs, design notes
|
||||||
|
- Tooling/skills: reusable, non-project-specific
|
||||||
|
- Project conventions: repo's own rules
|
||||||
|
- Feature/subsystem: one cohesive change
|
||||||
|
- Layer changes: app, sidecar CLI, daemon, IPC, pql wrapper, canvas, git panel
|
||||||
|
3. **Prefer many small focused commits over one large mixed one**
|
||||||
|
4. **Use `git add <specific paths>`** — NEVER `git add -A`, `git add .`, `git add -u`
|
||||||
|
5. **Verify between commits** with `git status`, `git diff --staged`, `git log -1`
|
||||||
|
|
||||||
|
### Changelog discipline
|
||||||
|
|
||||||
|
- **Every user-visible commit must touch CHANGELOG.md** under `## [Unreleased]`
|
||||||
|
- Use Keep a Changelog 1.1.0 format with sections: Added, Changed, Deprecated, Removed, Fixed, Security
|
||||||
|
- Entries: short imperative phrases describing user-facing impact
|
||||||
|
- **60 words hard cap per bullet** — verify with `make changelog-gate`
|
||||||
|
- What skips changelog: pure bookkeeping with no user-visible effect
|
||||||
|
|
||||||
|
### Safety rules (reinforced)
|
||||||
|
|
||||||
|
- **Never** `--no-verify`
|
||||||
|
- **Never** `--amend` unless user explicitly asks
|
||||||
|
- **Never** force-push to `main` or `master`
|
||||||
|
- **Always** check `git status` before staging, `git diff --staged` before committing
|
||||||
|
- Commit message via HEREDOC:
|
||||||
|
```bash
|
||||||
|
git commit -m "$(cat <<'EOF'
|
||||||
|
<message>
|
||||||
|
EOF
|
||||||
|
)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### What NOT to commit
|
||||||
|
|
||||||
|
- `.env`, `*.env.local`
|
||||||
|
- `.claude/settings.local.json`
|
||||||
|
- Build artefacts: `sidecar/bin/`, `sidecar/dist/`, `build/`, `app/.dart_tool/`
|
||||||
|
- SQLite index files: `*.sqlite`, `*.sqlite-wal`, `*.sqlite-shm`, `*.db`
|
||||||
|
- Coverage/test output: `*.out`, `coverage.*`, `*.test`
|
||||||
|
- `.pql/changelog/` — auto-staged by pre-commit hook from pql DB
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## pql — Vault Queries + Project Planning
|
||||||
|
|
||||||
|
`pql` indexes a vault into SQLite and exposes structural queries plus a
|
||||||
|
planning layer for decision records and tickets. One binary, two surfaces.
|
||||||
|
|
||||||
|
### Precondition
|
||||||
|
|
||||||
|
```bash
|
||||||
|
command -v pql
|
||||||
|
```
|
||||||
|
|
||||||
|
If absent, tell the user to install from
|
||||||
|
https://github.com/postmeridiem/pql/releases/latest. Don't install it
|
||||||
|
yourself. Don't fall back to grep unless the user explicitly asks.
|
||||||
|
|
||||||
|
### First touch: learn the vault
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pql schema
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns one row per frontmatter key with observed types and file counts.
|
||||||
|
Run once per session before writing queries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Surface 1: Vault queries
|
||||||
|
|
||||||
|
#### Subcommands
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `pql files [glob]` | List indexed files; optional glob filter |
|
||||||
|
| `pql tags [--sort count]` | Distinct tags with counts |
|
||||||
|
| `pql backlinks <path>` | Files linking TO a path |
|
||||||
|
| `pql outlinks <path>` | Links FROM a file |
|
||||||
|
| `pql meta <path>` | Frontmatter + tags + outlinks + headings for one file |
|
||||||
|
| `pql schema` | Typed frontmatter schema |
|
||||||
|
| `pql base <name>` | Execute an Obsidian .base file |
|
||||||
|
| `pql shell` | Interactive REPL (indexes once, then query per line) |
|
||||||
|
| `pql query "<DSL>"` | SQL-derived DSL for complex queries |
|
||||||
|
| `pql doctor` | Resolved vault/config/DB/index state |
|
||||||
|
|
||||||
|
#### DSL examples
|
||||||
|
|
||||||
|
```sql
|
||||||
|
SELECT name, fm.date WHERE fm.type = 'meeting' ORDER BY fm.date DESC LIMIT 10
|
||||||
|
SELECT path WHERE 'project' IN tags ORDER BY path
|
||||||
|
SELECT name, fm.prior_job WHERE fm.type = 'council-member' ORDER BY name
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `--file q.pql` or `--stdin` for long queries. Don't interpolate vault
|
||||||
|
content into the command line.
|
||||||
|
|
||||||
|
#### Query cookbook
|
||||||
|
|
||||||
|
- **Files in folder** → `pql files 'sessions/*'`
|
||||||
|
- **Top tags** → `pql tags --sort count --limit 20`
|
||||||
|
- **What links to X?** → `pql backlinks members/vaasa/persona.md`
|
||||||
|
- **Date range** → `pql query "SELECT name, fm.date WHERE fm.date BETWEEN '2024-01-01' AND '2024-12-31'"`
|
||||||
|
- **Run a Base** → `pql base council-sessions`
|
||||||
|
- **Inspect one file** → `pql meta members/vaasa/persona.md --pretty`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Surface 2: Planning (decisions + tickets)
|
||||||
|
|
||||||
|
Planning state lives in `<vault>/.pql/pql.db` (user-authored state, not a
|
||||||
|
cache). Decision records come from the DQR tree — `governance/{decisions,
|
||||||
|
questions,rejected}/<domain>.md` by default (D-21), configurable via
|
||||||
|
`dqr_dir` in `.pql/config.yaml` or the `PQL_DQR_DIR` env var (env > file >
|
||||||
|
default); a legacy flat `decisions/` is auto-detected as a fallback.
|
||||||
|
Tickets are SQLite-native.
|
||||||
|
|
||||||
|
#### Decision subcommands
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `pql decisions sync [--no-style]` | Parse the DQR tree → upsert into pql.db; surfaces style warnings (filename, subdir-type, domain pairing/conflicts) unless `--no-style` |
|
||||||
|
| `pql decisions validate [--no-style]` | Dry-run parse; structural errors exit non-zero, style issues warn (suppress with `--no-style`) |
|
||||||
|
| `pql decisions claim <D\|Q\|R> <domain> "title"` | Print next available ID |
|
||||||
|
| `pql decisions list [--type X] [--domain X] [--status X]` | List decisions |
|
||||||
|
| `pql decisions show <id> [--with-refs] [--with-tickets]` | Show with joins |
|
||||||
|
| `pql decisions coverage` | Confirmed decisions without tickets |
|
||||||
|
| `pql decisions refs <id>` | Cross-references involving a decision |
|
||||||
|
|
||||||
|
Always `pql decisions sync` before querying if decisions/*.md may have changed.
|
||||||
|
|
||||||
|
#### Ticket subcommands
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `pql ticket new <type> "title" [--parent T-NNN] [--decision D-NNN] [--priority P] [--id-only]` | Create (emits T-NNN; `--parent` files it under an epic/story in one step; `--id-only` prints the bare id for tree-creation scripts) |
|
||||||
|
| `pql ticket list [--status S] [--team T] [--assigned A] [--label L] [--under T-NNN] [--leaf] [--unblocked]` | List with filters. `--under` = recursive descendants of a ticket; `--leaf` = no children; `--unblocked` = blockers all reached a terminal status |
|
||||||
|
| `pql ticket show <id[,id,...]> [--with-context] [--with-blockers] [--with-children] [--tree] [--depth N]` | Show one or more (comma-batch → array of show-trees). `--with-children` = direct children; `--tree` = nested descendant subtree + direct parent (cap with `--depth N`) |
|
||||||
|
| `pql ticket status <id> <new-status> [--force]` | Change status. Closing (terminal status) is blocked while the ticket has open children; `--force` cascades that status to all not-yet-closed descendants and lists them |
|
||||||
|
| `pql ticket statuslist` | List the configured status vocabulary (name, label, class, order, is_default, is_terminal) — what a UI reads to render columns |
|
||||||
|
| `pql ticket relabel <id\|record_id> [--new-label T-NNN] [--fix-prose]` | Reassign a ticket's friendly T-NNN label (reconcile a duplicate-label collision). Identity (record_id) and the structural graph are untouched; only the label moves. `--fix-prose` rewrites stale T-NNN mentions in DQR markdown |
|
||||||
|
| `pql ticket assign <id> <agent>` | Set assignee |
|
||||||
|
| `pql ticket setparent <id[,id,...]> <parent-id \| none>` | Set (or clear with `none`) a ticket's **parent** — the hierarchy link (epic→story→task). Positional, not a flag. This is the parent/child relationship, distinct from blockers |
|
||||||
|
| `pql ticket append <id> <text\|--file\|--stdin>` | Append to the description (blank-line separated); never round-trips existing text |
|
||||||
|
| `pql ticket block <id> --by <other>` | Add a **blocker** (a dependency: <id> can't start until <other> is done) — NOT a parent/child link; use `setparent` or `new --parent` for hierarchy |
|
||||||
|
| `pql ticket unblock <id> --from <other>` | Remove blocker |
|
||||||
|
| `pql ticket team <id> <team>` | Set team |
|
||||||
|
| `pql ticket label <id> add\|rm <label>` | Manage labels |
|
||||||
|
| `pql ticket board [--team T]` | Kanban board view |
|
||||||
|
| `pql ticket refine list` | Tickets with empty descriptions, status-priority-sorted |
|
||||||
|
| `pql ticket refine next [--skip N]` | Head of the unrefined queue with full show-tree + remaining count |
|
||||||
|
| `pql ticket refine write <id> <json\|--file\|--stdin>` | Patch writable fields (title, description, priority, type) |
|
||||||
|
|
||||||
|
Ticket types: initiative, epic, story, task, bug.
|
||||||
|
The `id` you type and see (T-NNN) is a friendly label backed by a stable
|
||||||
|
underwater `record_id` (also in output); two clones never collide on identity,
|
||||||
|
and a duplicate label is fixed with `pql ticket relabel` (D-26).
|
||||||
|
Statuses are a per-vault vocabulary (`ticket_statuses` in `.pql/config.yaml`),
|
||||||
|
defaulting to: backlog, ready, in_progress, review, done, cancelled. Each status
|
||||||
|
has a class — initial, active, review, terminal — that the engine reasons about.
|
||||||
|
Run `pql ticket statuslist` to discover the live set. Any status can transition
|
||||||
|
to any other — pql does not enforce a state machine — except that a ticket
|
||||||
|
cannot reach a terminal status while it has open children (use `--force` to
|
||||||
|
cascade the close down the subtree).
|
||||||
|
|
||||||
|
#### Plan subcommands
|
||||||
|
|
||||||
|
| Command | Purpose |
|
||||||
|
|---|---|
|
||||||
|
| `pql plan status` | Dashboard: decision counts, open Qs, ticket summary, coverage gaps |
|
||||||
|
| `pql plan whatsnext` | Next ticket to work on (active work, then the "ready" lane) with full context bundle |
|
||||||
|
| `pql plan review` | Next ticket awaiting review with full context bundle |
|
||||||
|
| `pql plan export [--stage]` | Append changed planning rows to `.pql/changelog/<table>/<YYYY-MM>.sql` (the git-tracked log of record); `--stage` also `git add`s them. Normally a no-op — mutations already write through |
|
||||||
|
| `pql plan import [--legacy FILE]` | Replay `.pql/changelog/` into `pql.db` (or one-time `--legacy pql-plan.json` migration from the pre-D-15 snapshot) |
|
||||||
|
| `pql plan rebuild` | Drop replicated tables and replay `.pql/changelog/` from scratch. Warns on stderr (`changelog.ticket_id_collision`) + lists `collisions` in the result if one ticket id was filed twice across clones |
|
||||||
|
|
||||||
|
#### Versioning planning state
|
||||||
|
|
||||||
|
`pql.db` is gitignored — the durable, git-tracked artifact is
|
||||||
|
`.pql/changelog/` (D-15/D-16). Ticket mutations **write through** to the
|
||||||
|
changelog synchronously, so it is always current; you never have to
|
||||||
|
remember to "export". The hooks installed by `pql init` do the rest:
|
||||||
|
|
||||||
|
- `pre-commit` stages `.pql/changelog/` so it lands in the same commit as
|
||||||
|
the change that produced it.
|
||||||
|
- `post-merge` replays incoming changelog edits (`pql plan import`) and
|
||||||
|
re-syncs decisions from their markdown.
|
||||||
|
- `post-checkout` / `post-rewrite` rebuild `pql.db` from the changelog.
|
||||||
|
|
||||||
|
On a fresh clone, `pql plan import` (run automatically on first open)
|
||||||
|
replays the changelog into a new `pql.db`. There is **no** `pql-plan.json`
|
||||||
|
snapshot — that artifact is retired; `pql plan export` is now only a
|
||||||
|
manual catch-up/reconcile.
|
||||||
|
|
||||||
|
A ticket mutation (create / status transition / any write) leaves
|
||||||
|
`.pql/changelog/` dirty by design — the `pre-commit` hook stages it onto
|
||||||
|
the next `git commit`. This is expected, not a problem to flag. Don't
|
||||||
|
narrate "the ticket won't persist until committed" on every edit; either
|
||||||
|
fold the bookkeeping into a commit or trust the normal commit flow.
|
||||||
|
|
||||||
|
#### Planning cookbook
|
||||||
|
|
||||||
|
- **Sync and list confirmed** → `pql decisions sync && pql decisions list --type confirmed`
|
||||||
|
- **Show with refs** → `pql decisions show D-5 --with-refs --pretty`
|
||||||
|
- **Read full body** → `pql decisions read D-5`
|
||||||
|
- **Create ticket** → `pql ticket new task "implement X" --decision D-5`
|
||||||
|
- **Create ticket, capture id for a script** → `id=$(pql ticket new task "implement X" --id-only)` — prints just `T-NNN`
|
||||||
|
- **File a ticket under an epic** → `pql ticket new bug "fix X" --parent T-276` (one step), or reparent an existing one → `pql ticket setparent T-9 T-276` (clear with `none`). Parent = hierarchy; use `block` only for blocking dependencies
|
||||||
|
- **Batch close** → `pql ticket status T-1,T-2,T-3 done`
|
||||||
|
- **Full context** → `pql ticket show T-5 --with-context --pretty`
|
||||||
|
- **Batch show** → `pql ticket show T-1,T-2,T-3 --pretty`
|
||||||
|
- **Refine next ticket** → `pql ticket refine next --pretty`, then `pql ticket refine write T-N '{"description":"..."}'`
|
||||||
|
- **Append a note** → `pql ticket append T-5 "benchmarked; TTL now 5m"` — blank-line separated, never overwrites; use `--file note.md` or `--stdin` for longer content
|
||||||
|
- **Subtree of an epic** → `pql ticket show T-2 --tree --pretty` — nested `subtree` + direct parent in `ancestors`; add `--depth N` to cap levels
|
||||||
|
- **Ready leaf work under an epic** → `pql ticket list --under T-2 --leaf --unblocked` — leaf tickets beneath T-2 whose blockers have all reached a terminal status; the batch complement to `plan whatsnext`
|
||||||
|
- **What's next?** → `pql plan whatsnext --pretty`
|
||||||
|
- **Review queue** → `pql plan review --pretty`
|
||||||
|
- **Coverage gaps** → `pql decisions coverage`
|
||||||
|
- **Dashboard** → `pql plan status --pretty`
|
||||||
|
- **Force a changelog catch-up** → `pql plan export` (normally a no-op; mutations already write through to `.pql/changelog/`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Output contract (both surfaces)
|
||||||
|
|
||||||
|
- **stdout:** JSON array (default); `--jsonl` for one object/line; `--pretty`; `--limit N`.
|
||||||
|
- **stderr:** JSON diagnostics `{"level":"...","code":"pql.<phase>.<kind>","msg":"..."}`.
|
||||||
|
- **Exit codes:**
|
||||||
|
- `0` — success, including zero matches (empty `[]` — say "no matches", not "failed")
|
||||||
|
- `64` — bad flag
|
||||||
|
- `65` — parse/compile error (pass stderr back)
|
||||||
|
- `66` — vault/config not found
|
||||||
|
- `69` — unavailable
|
||||||
|
- `70` — internal error
|
||||||
|
|
||||||
|
### Anti-patterns
|
||||||
|
|
||||||
|
- Don't pipe to `jq` for simple projections — use `--limit`, `--pretty`, `--jsonl`.
|
||||||
|
- Don't chain `pql files` + `pql meta` — one `pql query` with WHERE.
|
||||||
|
- Don't parse errors — pass stderr diagnostics back directly.
|
||||||
|
- Don't forget `pql decisions sync` before querying decisions.
|
||||||
|
- Don't try to install or upgrade pql — instruct the user if missing.
|
||||||
|
|
||||||
|
### When NOT to use
|
||||||
|
|
||||||
|
- **Body text search** → `grep`/`rg`.
|
||||||
|
- **Reading file contents** → `Read` tool.
|
||||||
|
- **Code structure** → tree-sitter / LSP.
|
||||||
|
- **Modifying vault files** → `Write`/`Edit`. pql doesn't write to vault content.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Driving clide UI via CLI (from clide skill)
|
||||||
|
|
||||||
|
**Core principle: Every UI action has a CLI equivalent (D-6).**
|
||||||
|
Discover the live surface; don't hard-code it.
|
||||||
|
|
||||||
|
### Discover capabilities
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clide capabilities
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns JSON: every registered command, split into `subsystem` + `verb`,
|
||||||
|
with argument schema. **This is authoritative** — re-run it, don't trust
|
||||||
|
remembered lists.
|
||||||
|
|
||||||
|
### Slots (layout areas)
|
||||||
|
|
||||||
|
- `sidebar` — left
|
||||||
|
- `workspace` — center (where Claude lives)
|
||||||
|
- `context` — right
|
||||||
|
- `statusbar` — bottom
|
||||||
|
|
||||||
|
### Observe state
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# One-shot orientation
|
||||||
|
clide status
|
||||||
|
|
||||||
|
# Narrower snapshots
|
||||||
|
clide pane list
|
||||||
|
clide editor active
|
||||||
|
clide git status
|
||||||
|
```
|
||||||
|
|
||||||
|
### Drive UI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Open a doc in a GUI reader
|
||||||
|
clide ui open <reader> <ref>
|
||||||
|
# readers: tickets, decisions, markdown, diff
|
||||||
|
# examples:
|
||||||
|
clide ui open tickets T-123
|
||||||
|
clide ui open decisions D-456
|
||||||
|
clide ui open diff lib/src/foo.dart
|
||||||
|
clide ui open markdown docs/bar.md
|
||||||
|
|
||||||
|
# Show diff and scroll to file
|
||||||
|
clide ui diff lib/src/foo.dart
|
||||||
|
|
||||||
|
# Raise a toast
|
||||||
|
clide ui toast "message" --severity success|warning|error|info
|
||||||
|
|
||||||
|
# General: clide <subsystem> <verb> [args]
|
||||||
|
clide files list
|
||||||
|
clide editor open <path>
|
||||||
|
clide pane focus <pane-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Convention:** If a drive verb has no live GUI, return toolError
|
||||||
|
("no live UI to drive"), not hang. Exit code conveys ok/usage/tool error.
|
||||||
|
JSON on stdout.
|
||||||
|
|
||||||
|
### You only see what flows through clide
|
||||||
|
|
||||||
|
Your own non-`clide` shell work (plain file reads, `make test`, `git`) is
|
||||||
|
outside clide's view by design (D-83). Run it **through** `clide ...` if
|
||||||
|
you want clide to observe it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testmode (from testmode skill)
|
||||||
|
|
||||||
|
`ClideTestApp` is a lightweight Flutter app for integration testing.
|
||||||
|
Catches regressions unit tests cannot: missing binaries, broken subprocess
|
||||||
|
wiring, IPC dispatch failures, extension activation order, theme parse errors.
|
||||||
|
|
||||||
|
### Running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make run-testmode # all categories, 60s timeout
|
||||||
|
make run-testmode TESTMODE_CATEGORY=toolchain
|
||||||
|
make run-testmode TESTMODE_CATEGORY=ipc
|
||||||
|
make run-testmode TESTMODE_CATEGORY=extensions
|
||||||
|
make run-testmode TESTMODE_TIMEOUT=120
|
||||||
|
```
|
||||||
|
|
||||||
|
Results: stdout + `/tmp/clide-testmode.log`
|
||||||
|
Last line is machine-readable JSON: `{"passed":N,"failed":M,"total":N+M,"failures":[...]}`
|
||||||
|
|
||||||
|
### When to run
|
||||||
|
|
||||||
|
| Changed area | Category | Why |
|
||||||
|
|-------------|----------|-----|
|
||||||
|
| Toolchain, PATH, ptyc | `toolchain` | Binary resolution + exec |
|
||||||
|
| IPC envelope, dispatcher | `ipc` | Round-trip + error contract |
|
||||||
|
| Extension manifest, activate | `extensions` | Register + activate lifecycle |
|
||||||
|
| Theme YAML, loader | `extensions` | Theme parse is in this category |
|
||||||
|
| Platform config | `all` | Full rebuild validates everything |
|
||||||
|
| Any doubt | `all` | ~30s, cheap insurance |
|
||||||
|
|
||||||
|
### Interpreting output
|
||||||
|
|
||||||
|
- `[testmode] exec | ... | OK` — subprocess ran, exit 0 or 1
|
||||||
|
- `[testmode] PASS | ...` — assertion passed
|
||||||
|
- `[testmode] FAIL | ...` — assertion failed
|
||||||
|
- `[testmode] exec | ... | EXCEPTION` — binary not found or not executable
|
||||||
|
- `[testmode] exec | ... | TIMEOUT` — subprocess hung
|
||||||
|
|
||||||
|
If no `[testmode]` lines appear, the testmode gate didn't fire — verify
|
||||||
|
`CLIDE_TESTMODE` is set to a non-empty string.
|
||||||
|
|
||||||
|
### Adding tests
|
||||||
|
|
||||||
|
All test logic in `lib/test_app.dart`. Pattern:
|
||||||
|
```dart
|
||||||
|
await _testExec('label', binary, ['args'], workDir);
|
||||||
|
// or
|
||||||
|
_addResult('label', boolCondition, 'detail string');
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Repo Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
lib/
|
||||||
|
main.dart # Flutter entry point
|
||||||
|
app.dart # Root layout, workspace, panels
|
||||||
|
clide.dart # Barrel: shared types
|
||||||
|
src/ # Core subsystems (IPC, PTY, git, files, pql, panes)
|
||||||
|
kernel/ # Kernel services (theme, i18n, settings, panels)
|
||||||
|
builtin/ # Built-in extensions
|
||||||
|
widgets/ # Custom widget primitives
|
||||||
|
extension/ # Extension contract and registration
|
||||||
|
lua/ # Lua runtime support
|
||||||
|
|
||||||
|
test/ # All tests (core + widgets + goldens + a11y)
|
||||||
|
assets/ # Fonts, themes, grammars, licenses, logo
|
||||||
|
linux/, macos/, web/ # Flutter platform directories
|
||||||
|
native/ # Vendored native libs (tree-sitter, dugite)
|
||||||
|
governance/ # D/Q/R records
|
||||||
|
docs/ # Design docs, wireframes
|
||||||
|
legacy/ # Python Textual clide v1.2 (frozen)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependency & Supply Chain Discipline
|
||||||
|
|
||||||
|
- **Prefer-zero-deps.** Flutter-SDK widgets first; third-party needs justification
|
||||||
|
- **Exact-pinned in pubspec.yaml** — no caret ranges
|
||||||
|
- **Advisories reviewed** before every bump
|
||||||
|
- **pubspec.lock committed**
|
||||||
|
- **Document every bundled dependency** in `assets/licenses.yaml`:
|
||||||
|
- name, kind, version, homepage, license, purpose
|
||||||
|
- Adding a dep: two-step commit — artefact AND `licenses.yaml` entry
|
||||||
|
- Native deps (dugite, libtree-sitter): vendored in `native/`, pinned by SHA
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Pre-push Gate
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make push-check
|
||||||
|
```
|
||||||
|
|
||||||
|
Runs: decisions validation + core tests + fast suite + a11y + coverage + changelog
|
||||||
|
|
||||||
|
**Never bypass.** If it fails, fix the underlying issue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session Setup
|
||||||
|
|
||||||
|
One-time setup on fresh clone:
|
||||||
|
```bash
|
||||||
|
make hooks && flutter pub get
|
||||||
|
pql init # wires up pql skill + perms
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mistral-Specific Notes
|
||||||
|
|
||||||
|
### What to preserve from Claude
|
||||||
|
|
||||||
|
- CLI-first interaction model
|
||||||
|
- Strict guardrails enforcement
|
||||||
|
- Logically-separated commits
|
||||||
|
- Changelog discipline (60-word cap)
|
||||||
|
- pql as single source of truth for decisions/tickets
|
||||||
|
- UI/CLI parity
|
||||||
|
- Testmode for integration validation
|
||||||
|
|
||||||
|
### What to adapt
|
||||||
|
|
||||||
|
- **Tool names:** Claude's `Bash(...)` → my `bash` tool
|
||||||
|
- **Agent spawning:** Claude's `Agent{}` → my `task` tool for subagents
|
||||||
|
- **Permissions:** `.claude/settings.json` allow/deny → my system prompt + your instructions
|
||||||
|
|
||||||
|
### When in doubt
|
||||||
|
|
||||||
|
Ask: "What would Claude do?" Then do that. The AGENTS.md is the bridge,
|
||||||
|
not a replacement.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Reference Card
|
||||||
|
|
||||||
|
| Task | Command |
|
||||||
|
|------|---------|
|
||||||
|
| Discover clide commands | `clide capabilities` |
|
||||||
|
| See current UI state | `clide status` |
|
||||||
|
| Open ticket in UI | `clide ui open tickets T-NNN` |
|
||||||
|
| Toast notification | `clide ui toast "msg" --severity info` |
|
||||||
|
| List actionable tickets | `pql ticket list --under <id> --leaf --unblocked --status backlog --pretty` |
|
||||||
|
| Sync decisions | `pql decisions sync` |
|
||||||
|
| Run integration tests | `make run-testmode` |
|
||||||
|
| Fast test suite | `make test` |
|
||||||
|
| Full pre-push | `make push-check` |
|
||||||
|
| Commit with message | `git commit -m "$(cat <<'EOF'\n<message>\nEOF\n)"` |
|
||||||
|
| Verify changelog | `make changelog-gate` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated for Mistral Vibe. Preserves Claude Code punch for clide repo.*
|
||||||
+1395
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@ An IDE for Claude Code CLI. Single Flutter package at the repo root.
|
|||||||
- **`lib/`** — all Dart code. Subsystem handlers (`lib/src/daemon/`, `lib/src/pty/`, `lib/src/ipc/`, `lib/src/git/`, `lib/src/pql/`), kernel services (`lib/kernel/`), UI widgets (`lib/widgets/`), built-in extensions (`lib/builtin/`), and the extension framework (`lib/extension/`). The Flutter app hosts the IPC server in-process (D-56). PTY spawning uses Dart FFI `posix_openpt()` + `posix_spawn()` directly.
|
- **`lib/`** — all Dart code. Subsystem handlers (`lib/src/daemon/`, `lib/src/pty/`, `lib/src/ipc/`, `lib/src/git/`, `lib/src/pql/`), kernel services (`lib/kernel/`), UI widgets (`lib/widgets/`), built-in extensions (`lib/builtin/`), and the extension framework (`lib/extension/`). The Flutter app hosts the IPC server in-process (D-56). PTY spawning uses Dart FFI `posix_openpt()` + `posix_spawn()` directly.
|
||||||
- **[`pql`](https://github.com/postmeridiem/pql)** — external supporter tool. Clide wraps it for every query surface; never re-implements it.
|
- **[`pql`](https://github.com/postmeridiem/pql)** — external supporter tool. Clide wraps it for every query surface; never re-implements it.
|
||||||
|
|
||||||
tmux owns Claude session persistence (D-41) — the app re-attaches on restart via `tmux new-session -A`. Native rendering — markdown, canvas, graph — is Dart/Flutter (`CustomPaint` + widgets), not third-party packages.
|
Claude session persistence is `--resume <session-id>` against Claude Code's transcript files (D-77, superseding the original tmux-backed D-41) — the app re-attaches on restart, no tmux required. Native rendering — markdown, canvas, graph — is Dart/Flutter (`CustomPaint` + widgets), not third-party packages.
|
||||||
|
|
||||||
Design doc: [`docs/initial-plan.md`](docs/initial-plan.md). Decisions: [`governance/`](governance/) (`D-NNN` confirmed, `Q-NNN` open, `R-NNN` rejected — see [`governance/README.md`](governance/README.md)). Python Textual predecessor under [`legacy/`](legacy/).
|
Design doc: [`docs/initial-plan.md`](docs/initial-plan.md). Decisions: [`governance/`](governance/) (`D-NNN` confirmed, `Q-NNN` open, `R-NNN` rejected — see [`governance/README.md`](governance/README.md)). Python Textual predecessor under [`legacy/`](legacy/).
|
||||||
|
|
||||||
@@ -76,6 +76,23 @@ make clean # remove build artefacts
|
|||||||
|
|
||||||
One-time setup on a fresh clone: `make hooks && flutter pub get` once Flutter is installed.
|
One-time setup on a fresh clone: `make hooks && flutter pub get` once Flutter is installed.
|
||||||
|
|
||||||
|
### Tooling discipline
|
||||||
|
|
||||||
|
The `make` targets above are the entry points — run them, not the scripts they wrap. Check the changelog with `make changelog-gate`, never `ci/changelog_gate.sh` directly; same for `analyze`/`format`/`test`/`push-check`. The `make` layer sets up the environment and stays correct if a script moves.
|
||||||
|
|
||||||
|
Shell hygiene (keeps commands inside the permission allowlist, so they don't get denied mid-task):
|
||||||
|
- **Working directory is the repo root already** — don't prepend `cd /…/clide` or pass `git -C`. Just run the command.
|
||||||
|
- **One command per invocation** — no `&&`/`;` chaining and no multiple greps/echos in one call. The only exception is the `git commit -F` HEREDOC.
|
||||||
|
- Prefer the Read/Edit/Grep tools over `cat`/`sed`/`grep` for inspecting files.
|
||||||
|
|
||||||
|
## Git workflow
|
||||||
|
|
||||||
|
Commit and push directly to `main` for routine work — this is a solo-dev repo and does not use a branch-first / feature-branch flow. Do **not** create a working branch just to land a change. (This overrides the generic "branch before committing on the default branch" assistant default.) The usual safety rules still hold: never `--no-verify`, never force-push `main`, and let the pre-push gate run.
|
||||||
|
|
||||||
|
**Never `git add -A` or `git add .` — stage explicit paths every time (`git add <file> …`), no exceptions.** This worktree can host concurrent Claude sessions: a blanket add vacuums another session's in-progress files — and your own unrelated edits — into your commit, mislabeling work and entangling history (this has happened). If `git status` shows files you didn't touch this turn, they are not yours to stage. **Always create commits through the [`git-commit` skill](.claude/skills/git-commit/SKILL.md)** — it encodes the message format (Conventional Commits, per [D-37](governance/decisions/process.md#d-37)), the explicit-staging rule, changelog discipline, and the safety reminders. Don't hand-roll a commit that skips it.
|
||||||
|
|
||||||
|
The pre-commit hook auto-exports and stages `.pql/changelog/` (the pql ticket DB) on every commit — don't hand-stage it. A ticket change only persists if the turn makes at least one commit; with no commit the hook never fires and a later branch switch can drop it.
|
||||||
|
|
||||||
## Changelog discipline
|
## Changelog discipline
|
||||||
|
|
||||||
[Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/). Every user-visible commit adds an entry under `## [Unreleased]` in [`CHANGELOG.md`](CHANGELOG.md). Cutting a release means moving Unreleased entries under a new dated version heading **and** bumping `pubspec.yaml` `version:` in the same commit — see [`.claude/skills/git-commit/SKILL.md`](.claude/skills/git-commit/SKILL.md) for the full rule.
|
[Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/). Every user-visible commit adds an entry under `## [Unreleased]` in [`CHANGELOG.md`](CHANGELOG.md). Cutting a release means moving Unreleased entries under a new dated version heading **and** bumping `pubspec.yaml` `version:` in the same commit — see [`.claude/skills/git-commit/SKILL.md`](.claude/skills/git-commit/SKILL.md) for the full rule.
|
||||||
|
|||||||
+96
-11
@@ -17,21 +17,24 @@ cd clide
|
|||||||
make hooks && flutter pub get
|
make hooks && flutter pub get
|
||||||
```
|
```
|
||||||
|
|
||||||
`make hooks` installs the repo's git hooks (pre-commit + post-merge).
|
`make hooks` points `core.hooksPath` at [`.githooks/`](.githooks). The
|
||||||
Flutter must be on the stable channel and on `$PATH`.
|
load-bearing one is **pre-push** (runs `make push-check`); the rest
|
||||||
|
(pre-commit, post-checkout/merge/rewrite) are housekeeping. Flutter must
|
||||||
|
be on the stable channel and on `$PATH`.
|
||||||
|
|
||||||
If you haven't used [pql](https://github.com/postmeridiem/pql) before,
|
If you haven't used [pql](https://github.com/postmeridiem/pql) before,
|
||||||
install it and run `pql init` once in the repo root. pql is a hard
|
install it and run `pql init` once in the repo root. pql is a hard
|
||||||
dependency for the governance + ticket workflow described below.
|
dependency for the governance + ticket workflow described below.
|
||||||
|
|
||||||
## The five commands you'll actually use
|
## The commands you'll actually use
|
||||||
|
|
||||||
```
|
```
|
||||||
make run # launch the desktop app
|
make run # launch the desktop app
|
||||||
make verify # no-tests sweep — analyze + format + decisions + changelog gate
|
make verify # no-tests sweep — analyze + format + decisions + changelog gate
|
||||||
make test # fast suite — analyze + format + unit + widget + golden
|
make test # fast dev loop — analyze + format + unit + widget + golden, NO coverage, parallel (~20s)
|
||||||
|
make test-coverage # same suite WITH coverage (writes coverage/lcov.info; used by the gate)
|
||||||
make test-a11y # WCAG-AA contrast + keyboard traversal contracts
|
make test-a11y # WCAG-AA contrast + keyboard traversal contracts
|
||||||
make push-check # the pre-push gate; what CI runs
|
make push-check # the pre-push gate; what CI runs (runs test-coverage, not the no-coverage test)
|
||||||
make build-linux # release artefact for the host platform
|
make build-linux # release artefact for the host platform
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -49,13 +52,91 @@ commit. Pre-push includes:
|
|||||||
|
|
||||||
- `flutter analyze` (zero warnings)
|
- `flutter analyze` (zero warnings)
|
||||||
- `dart format --set-exit-if-changed`
|
- `dart format --set-exit-if-changed`
|
||||||
- the fast unit/widget/golden suites
|
- the core (`dart test`) suite
|
||||||
- accessibility contract tests
|
- the unit/widget/golden/a11y suites, instrumented for coverage
|
||||||
|
(`make test-coverage` — the a11y suite runs here, not as a separate pass)
|
||||||
- a coverage floor read from `coverage_floor:` in `pubspec.yaml`
|
- a coverage floor read from `coverage_floor:` in `pubspec.yaml`
|
||||||
(currently 95 %; ratchets up only — see
|
(currently 95 %; ratchets up only — see
|
||||||
[D-66](governance/decisions/testing.md#d-66))
|
[D-66](governance/decisions/testing.md#d-66))
|
||||||
- `CHANGELOG.md` `[Unreleased]` bullets ≤ 60 words each
|
- `CHANGELOG.md` `[Unreleased]` bullets ≤ 60 words each
|
||||||
|
|
||||||
|
## The C `clide` shell client
|
||||||
|
|
||||||
|
`clide` (the binary) is a ~250 LOC C program in
|
||||||
|
[`native/clide-cli/clide.c`](native/clide-cli/clide.c) that talks to
|
||||||
|
the running Flutter app's IPC socket so Claude (and you) can drive
|
||||||
|
clide from any shell. It walks CWD up to the workspace's `.git`,
|
||||||
|
computes the same FNV-1a 64-bit hash the Dart side uses (per D-70),
|
||||||
|
opens the per-workspace socket, and sends argv across the wire under
|
||||||
|
a sentinel `_argv` cmd. The argv parser lives in Dart
|
||||||
|
([`lib/src/cli/argv_to_request.dart`](lib/src/cli/argv_to_request.dart)),
|
||||||
|
so the C side stays a dumb pipe.
|
||||||
|
|
||||||
|
Build it with `make clide-cli` — output lands at
|
||||||
|
`native/<platform>/clide` (gitignored). Drop that on your PATH (or
|
||||||
|
symlink) and `clide status` works from any directory inside a clide
|
||||||
|
workspace once the app is running. Standard POSIX + libc only;
|
||||||
|
pure C99; no third-party deps.
|
||||||
|
|
||||||
|
The cross-language hash agreement is load-bearing — if the Dart
|
||||||
|
server and C client disagree on the socket path, every shell
|
||||||
|
invocation fails to connect. The test suite covers it:
|
||||||
|
[`test/ipc/paths_test.dart`](test/ipc/paths_test.dart) pins
|
||||||
|
FNV-1a vectors against the reference, and
|
||||||
|
[`test/cli/clide_cli_e2e_test.dart`](test/cli/clide_cli_e2e_test.dart)
|
||||||
|
compiles the C client and exercises the full round-trip.
|
||||||
|
|
||||||
|
## Running clide from the shell
|
||||||
|
|
||||||
|
Once the desktop app is running and `clide` is on your `$PATH`, every
|
||||||
|
shell inside the workspace can drive it. The argv grammar is fixed by
|
||||||
|
[D-6](governance/decisions/architecture.md#d-6-cli-and-event-surface-contract)
|
||||||
|
— every UI affordance has a CLI counterpart, and every CLI verb has a
|
||||||
|
UI affordance.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
clide status # one-shot snapshot of pane state
|
||||||
|
clide ping # round-trip health check
|
||||||
|
clide tail --events # stream every subsystem event
|
||||||
|
clide tail --events --filter git # stream a single subsystem
|
||||||
|
clide pane focus editor # drive the running app
|
||||||
|
clide panel toggle git # show/hide a panel
|
||||||
|
clide panel resize sidebar --to 320 # absolute width (px)
|
||||||
|
clide panel resize context --by -40 # relative nudge (px)
|
||||||
|
clide panel resize editor --to 0.5 # editor split ratio (0.15–0.70)
|
||||||
|
```
|
||||||
|
|
||||||
|
Output is JSON on stdout, one envelope per line. Streaming verbs
|
||||||
|
(`tail --events`) keep the connection open and emit one event line per
|
||||||
|
push; Ctrl-C cleanly closes the socket. Exit codes follow the pql
|
||||||
|
convention ([D-68](governance/decisions/architecture.md#d-68-cli-and-mcp-surface-contracts)):
|
||||||
|
|
||||||
|
| Code | Meaning |
|
||||||
|
|------|------------------------------------------------------|
|
||||||
|
| 0 | success |
|
||||||
|
| 64 | user error — bad argv, unknown verb, malformed flag |
|
||||||
|
| 65 | data error — request well-formed but rejected |
|
||||||
|
| 69 | service unavailable — no running clide for this repo |
|
||||||
|
| 70 | internal error — dispatcher threw |
|
||||||
|
|
||||||
|
If `clide` exits 69, the desktop app isn't running for this workspace
|
||||||
|
— start it with `make run` (during development) or launch the
|
||||||
|
installed app pointed at this repo.
|
||||||
|
|
||||||
|
### Claude Code's `/ide` and the MCP server
|
||||||
|
|
||||||
|
The desktop app also runs an MCP companion server on a random
|
||||||
|
localhost port (HTTP + Server-Sent Events, per
|
||||||
|
[D-73](governance/decisions/architecture.md#d-73-mcp-server-transport-over-http-sse)).
|
||||||
|
Discovery follows the Claude Code `/ide` contract: clide writes a
|
||||||
|
JSON descriptor to `~/.claude/ide/<pid>.lock` containing the chosen
|
||||||
|
port, the workspace root, and the protocol version. Claude Code's
|
||||||
|
`/ide` command picks the lock for the workspace it's running in and
|
||||||
|
connects automatically — no manual configuration. The lock is removed
|
||||||
|
on graceful shutdown; stale locks from crashed processes are reaped
|
||||||
|
on the next start. The implementation lives in
|
||||||
|
[`lib/src/ipc/mcp_server.dart`](lib/src/ipc/mcp_server.dart).
|
||||||
|
|
||||||
## Decisions, questions, rejected (DQR)
|
## Decisions, questions, rejected (DQR)
|
||||||
|
|
||||||
clide tracks architectural commitments as durable records under
|
clide tracks architectural commitments as durable records under
|
||||||
@@ -100,14 +181,18 @@ tickets before the diff lands. Trivial typo fixes don't need one.
|
|||||||
See [D-37](governance/decisions/process.md#d-37) and the bundled
|
See [D-37](governance/decisions/process.md#d-37) and the bundled
|
||||||
[`git-commit` skill](.claude/skills/git-commit/SKILL.md). In short:
|
[`git-commit` skill](.claude/skills/git-commit/SKILL.md). In short:
|
||||||
|
|
||||||
- Imperative subject ≤ 70 chars, no Conventional Commits prefix
|
- [Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/):
|
||||||
(this isn't a Conventional Commits repo — the archived Python
|
`type(scope): imperative subject`, ≤ 72 chars including the prefix.
|
||||||
predecessor under [`legacy/`](legacy/) is, but the rebuild isn't).
|
Types are `feat`, `fix`, `docs`, `style`, `refactor`, `perf`,
|
||||||
|
`test`, `build`, `chore`; scope is the subsystem (`settings`,
|
||||||
|
`vim`, `pty`…); keep a trailing `(T-NNN)` ticket ref where one
|
||||||
|
applies — e.g. `feat(settings): category rail + navigation (T-447)`.
|
||||||
- One logical change per commit. If the subject needs "and", split it.
|
- One logical change per commit. If the subject needs "and", split it.
|
||||||
- Every user-visible commit adds an entry to `CHANGELOG.md` under
|
- Every user-visible commit adds an entry to `CHANGELOG.md` under
|
||||||
`[Unreleased]` in the right subsection (Added, Changed, Deprecated,
|
`[Unreleased]` in the right subsection (Added, Changed, Deprecated,
|
||||||
Removed, Fixed, Security). Keep entries to one or two short
|
Removed, Fixed, Security). Keep entries to one or two short
|
||||||
sentences — the 60-word cap is enforced by `ci/changelog_gate.sh`.
|
sentences — the 60-word cap is enforced by the pre-push gate
|
||||||
|
(`make changelog-gate`).
|
||||||
- Co-author trailer:
|
- Co-author trailer:
|
||||||
`Co-Authored-By: Claude <noreply@anthropic.com>` when Claude wrote
|
`Co-Authored-By: Claude <noreply@anthropic.com>` when Claude wrote
|
||||||
any of the diff.
|
any of the diff.
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
VERSION ?= $(shell awk -F': *' '/^version:/ {gsub(/[" ]/,"",$$2); print $$2; exit}' pubspec.yaml)
|
VERSION ?= $(shell awk -F': *' '/^version:/ {gsub(/[" ]/,"",$$2); print $$2; exit}' pubspec.yaml)
|
||||||
|
NAME ?= $(shell awk -F': *' '/^name:/ {gsub(/[" ]/,"",$$2); print $$2; exit}' pubspec.yaml)
|
||||||
|
TAGLINE ?= $(shell awk -F': *' '/^tagline:/ {sub(/^tagline: *"?/,"",$$0); sub(/"$$/,"",$$0); print; exit}' pubspec.yaml)
|
||||||
|
REPOSITORY ?= $(shell awk -F': *' '/^repository:/ {sub(/^repository: */,"",$$0); print; exit}' pubspec.yaml)
|
||||||
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
@@ -28,11 +32,14 @@ help: ## Show this help.
|
|||||||
# -- app (Flutter) -------------------------------------------------------
|
# -- app (Flutter) -------------------------------------------------------
|
||||||
|
|
||||||
.PHONY: run
|
.PHONY: run
|
||||||
run: ## Launch the Flutter desktop app.
|
run: gen-build-info clide-cli ## Launch the Flutter desktop app.
|
||||||
|
# CLIDE_CLI_BIN points the in-app "Install clide command in PATH"
|
||||||
|
# affordance (T-212) at the dev-tree C client; a packaged build finds it
|
||||||
|
# beside the GUI runner in the bundle instead.
|
||||||
ifeq ($(FLUTTER_OS),linux)
|
ifeq ($(FLUTTER_OS),linux)
|
||||||
GDK_BACKEND=x11 LD_LIBRARY_PATH=$(CURDIR)/native/linux-x64$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} flutter run -d linux --dart-define=CLIDE_PROJECT=$(CURDIR)
|
CLIDE_CLI_BIN=$(CURDIR)/$(CLIDE_CLI_BIN) GDK_BACKEND=x11 LD_LIBRARY_PATH=$(CURDIR)/native/linux-x64$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} flutter run -d linux --dart-define=CLIDE_PROJECT=$(CURDIR)
|
||||||
else
|
else
|
||||||
flutter run -d $(FLUTTER_OS) --dart-define=CLIDE_PROJECT=$(CURDIR)
|
CLIDE_CLI_BIN=$(CURDIR)/$(CLIDE_CLI_BIN) flutter run -d $(FLUTTER_OS) --dart-define=CLIDE_PROJECT=$(CURDIR)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
TESTMODE_CATEGORY ?= all
|
TESTMODE_CATEGORY ?= all
|
||||||
@@ -64,7 +71,7 @@ pubget: ## flutter pub get.
|
|||||||
flutter pub get
|
flutter pub get
|
||||||
|
|
||||||
.PHONY: build-check
|
.PHONY: build-check
|
||||||
build-check: ## Verify native + Dart build compiles (no run).
|
build-check: gen-build-info ## Verify native + Dart build compiles (no run).
|
||||||
ifeq ($(FLUTTER_OS),linux)
|
ifeq ($(FLUTTER_OS),linux)
|
||||||
LD_LIBRARY_PATH=$(CURDIR)/native/linux-x64$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} flutter build linux
|
LD_LIBRARY_PATH=$(CURDIR)/native/linux-x64$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH} flutter build linux
|
||||||
else
|
else
|
||||||
@@ -79,23 +86,50 @@ analyze: ## flutter analyze.
|
|||||||
format: ## dart format --set-exit-if-changed.
|
format: ## dart format --set-exit-if-changed.
|
||||||
dart format --set-exit-if-changed .
|
dart format --set-exit-if-changed .
|
||||||
|
|
||||||
|
# The single bake of every build-time fact derived from pubspec.yaml
|
||||||
|
# + git + clock. Runs implicitly as a prereq of every target that
|
||||||
|
# compiles or executes Dart code so nobody has to remember it.
|
||||||
|
#
|
||||||
|
# Outputs:
|
||||||
|
# - lib/src/build_info.g.dart — gitignored, fresh on every build.
|
||||||
|
# Exposes `clideName`, `clideTagline`, `clideVersion`, `clideRepository`
|
||||||
|
# (from pubspec), `clideCommit` (git short SHA), `clideDate` (UTC
|
||||||
|
# now) for the app to read directly.
|
||||||
|
# - assets/licenses.yaml `self.version:` — rewritten in place so the
|
||||||
|
# bundled license manifest never drifts from pubspec. (Tracked in
|
||||||
|
# git; the rewrite is a no-op when in sync.)
|
||||||
|
.PHONY: gen-build-info
|
||||||
|
gen-build-info:
|
||||||
|
@printf '// GENERATED — do not edit. Regenerated by `make` on every\n// build/run/test (see gen-build-info in Makefile). Name / tagline /\n// version / repository come from pubspec.yaml — the single source\n// of truth. Commit + date stamp at run time.\nconst String clideName = '"'"'%s'"'"';\nconst String clideTagline = '"'"'%s'"'"';\nconst String clideVersion = '"'"'%s'"'"';\nconst String clideRepository = '"'"'%s'"'"';\nconst String clideCommit = '"'"'%s'"'"';\nconst String clideDate = '"'"'%s'"'"';\n' "$(NAME)" "$(TAGLINE)" "$(VERSION)" "$(REPOSITORY)" "$(COMMIT)" "$(DATE)" > lib/src/build_info.g.dart
|
||||||
|
@awk -v v="$(VERSION)" '/^self:/ {in_self=1} in_self && /^[[:space:]]+version:/ {sub(/version:.*/, "version: \"" v "\""); in_self=0} {print}' assets/licenses.yaml > assets/licenses.yaml.tmp && mv assets/licenses.yaml.tmp assets/licenses.yaml
|
||||||
|
|
||||||
.PHONY: verify
|
.PHONY: verify
|
||||||
verify: analyze format decisions-validate changelog-gate ## No-tests sweep — analyze + format + decisions-validate + changelog-gate. For mid-edit "are the gates green?" checks; `push-check` is the full pre-push pipeline.
|
verify: gen-build-info analyze format decisions-validate changelog-gate ## No-tests sweep — gen-build-info + analyze + format + decisions-validate + changelog-gate. For mid-edit "are the gates green?" checks; `push-check` is the full pre-push pipeline.
|
||||||
|
|
||||||
|
.PHONY: t
|
||||||
|
t: gen-build-info ## Run one test path with tee'd output. Usage: make t T=test/path/to/spec.dart
|
||||||
|
@mkdir -p test/.test-output
|
||||||
|
@if [ -z "$(T)" ]; then echo "usage: make t T=test/path/to/spec.dart" >&2; exit 2; fi
|
||||||
|
flutter test $(T) 2>&1 | tee test/.test-output/last.log
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test: ## Fast: analyze + format + unit + widget + golden (<60s).
|
test: gen-build-info ## Fast dev loop: analyze + format + unit + widget + golden, NO coverage, parallel (~20s).
|
||||||
ci/test.sh
|
ci/test.sh
|
||||||
|
|
||||||
|
.PHONY: test-coverage
|
||||||
|
test-coverage: gen-build-info ## Same suite WITH coverage → coverage/lcov.info (for the gate / CI). Slower.
|
||||||
|
ci/test.sh --coverage
|
||||||
|
|
||||||
.PHONY: test-core
|
.PHONY: test-core
|
||||||
test-core: ## Core subsystem tests (IPC, PTY, git, pane registry).
|
test-core: gen-build-info ## Core subsystem tests (IPC, PTY, git, pane registry).
|
||||||
ci/test_core.sh
|
ci/test_core.sh
|
||||||
|
|
||||||
.PHONY: test-a11y
|
.PHONY: test-a11y
|
||||||
test-a11y: ## A11y contract (semantic coverage + keyboard + contrast + i18n).
|
test-a11y: gen-build-info ## A11y contract (semantic coverage + keyboard + contrast + i18n).
|
||||||
ci/test_a11y.sh
|
ci/test_a11y.sh
|
||||||
|
|
||||||
.PHONY: test-integration
|
.PHONY: test-integration
|
||||||
test-integration: ## Integration tests (real app boot; xvfb on headless Linux).
|
test-integration: gen-build-info ## Integration tests (real app boot; xvfb on headless Linux).
|
||||||
ci/test_integration.sh
|
ci/test_integration.sh
|
||||||
|
|
||||||
.PHONY: test-e2e
|
.PHONY: test-e2e
|
||||||
@@ -106,7 +140,7 @@ test-e2e: ## End-to-end Playwright smoke.
|
|||||||
test-all: test-core test test-a11y test-integration test-e2e ## Everything, sequentially.
|
test-all: test-core test test-a11y test-integration test-e2e ## Everything, sequentially.
|
||||||
|
|
||||||
.PHONY: coverage-gate
|
.PHONY: coverage-gate
|
||||||
coverage-gate: ## Coverage gate — fails if total line % < pubspec.yaml `coverage_floor:` (D-66). Assumes `make test` ran first.
|
coverage-gate: ## Coverage gate — fails if total line % < pubspec.yaml `coverage_floor:` (D-66). Assumes `make test-coverage` ran first.
|
||||||
ci/coverage_gate.sh
|
ci/coverage_gate.sh
|
||||||
|
|
||||||
.PHONY: changelog-gate
|
.PHONY: changelog-gate
|
||||||
@@ -114,7 +148,7 @@ changelog-gate: ## Changelog concision gate — fails on `## [Unreleased]` bulle
|
|||||||
ci/changelog_gate.sh
|
ci/changelog_gate.sh
|
||||||
|
|
||||||
.PHONY: smoke-bundle
|
.PHONY: smoke-bundle
|
||||||
smoke-bundle: ## Build Linux release bundle and run it under xvfb for 5s.
|
smoke-bundle: gen-build-info ## Build Linux release bundle and run it under xvfb for 5s.
|
||||||
ci/smoke_bundle.sh
|
ci/smoke_bundle.sh
|
||||||
|
|
||||||
# -- web UI harness ------------------------------------------------------
|
# -- web UI harness ------------------------------------------------------
|
||||||
@@ -135,17 +169,26 @@ ui-smoke: ## Build + serve + run Playwright smoke + stop.
|
|||||||
@sh -c 'trap "tools/ui/stop.sh >/dev/null 2>&1" EXIT; cd tools/ui && npx playwright test smoke.spec.ts'
|
@sh -c 'trap "tools/ui/stop.sh >/dev/null 2>&1" EXIT; cd tools/ui && npx playwright test smoke.spec.ts'
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build: ## flutter build for the current OS.
|
build: clide-cli build-$(FLUTTER_OS) ## flutter build for the current OS (via build-<os>) + bundle the C CLI client.
|
||||||
flutter build $(FLUTTER_OS)
|
@install -m 755 $(CLIDE_CLI_BIN) $(CLI_BUNDLE_DEST)
|
||||||
|
@echo "==> bundled C client at $(CLI_BUNDLE_DEST)"
|
||||||
|
|
||||||
.PHONY: build-linux
|
.PHONY: build-linux
|
||||||
build-linux: ## flutter build linux (desktop bundle).
|
build-linux: gen-build-info ## flutter build linux (desktop bundle).
|
||||||
flutter build linux
|
flutter build linux
|
||||||
|
|
||||||
.PHONY: build-macos
|
.PHONY: build-macos
|
||||||
build-macos: ## flutter build macos (desktop bundle).
|
build-macos: gen-build-info ## flutter build macos (desktop bundle).
|
||||||
flutter build macos
|
flutter build macos
|
||||||
|
|
||||||
|
.PHONY: build-windows
|
||||||
|
build-windows: gen-build-info ## flutter build windows (desktop bundle).
|
||||||
|
flutter build windows
|
||||||
|
|
||||||
|
.PHONY: release
|
||||||
|
release: ## Finalize a release: verify version/changelog/tree, run the gate, tag vX.Y.Z. Run after the `release vX.Y.Z` commit.
|
||||||
|
ci/release.sh
|
||||||
|
|
||||||
# -- install / uninstall -----------------------------------------------------
|
# -- install / uninstall -----------------------------------------------------
|
||||||
|
|
||||||
# Install prefix. Bundle lands at $(INSTALL_PREFIX)/clide/ with a
|
# Install prefix. Bundle lands at $(INSTALL_PREFIX)/clide/ with a
|
||||||
@@ -154,19 +197,26 @@ INSTALL_PREFIX ?= $(HOME)/.local/lib
|
|||||||
|
|
||||||
ifeq ($(FLUTTER_OS),linux)
|
ifeq ($(FLUTTER_OS),linux)
|
||||||
BUNDLE_DIR := build/linux/x64/release/bundle
|
BUNDLE_DIR := build/linux/x64/release/bundle
|
||||||
|
# The C client ships beside the GUI runner so the in-app "Install clide
|
||||||
|
# command in PATH" affordance (T-212) can self-install from the bundle.
|
||||||
|
CLI_BUNDLE_DEST := $(BUNDLE_DIR)/clide-cli
|
||||||
else ifeq ($(FLUTTER_OS),macos)
|
else ifeq ($(FLUTTER_OS),macos)
|
||||||
BUNDLE_DIR := build/macos/Build/Products/Release/clide.app
|
BUNDLE_DIR := build/macos/Build/Products/Release/clide.app
|
||||||
|
CLI_BUNDLE_DEST := $(BUNDLE_DIR)/Contents/MacOS/clide-cli
|
||||||
|
else ifeq ($(FLUTTER_OS),windows)
|
||||||
|
BUNDLE_DIR := build/windows/x64/runner/Release
|
||||||
|
CLI_BUNDLE_DEST := $(BUNDLE_DIR)/clide-cli.exe
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ICON_SIZES := 16 32 48 128 192 256 512
|
ICON_SIZES := 16 32 48 128 192 256 512
|
||||||
|
|
||||||
.PHONY: install
|
.PHONY: install
|
||||||
install: build ## Build + install clide to ~/.local (INSTALL_PREFIX, INSTALL_DIR).
|
install: build clide-cli ## Build + install clide to ~/.local (INSTALL_PREFIX, INSTALL_DIR).
|
||||||
ifeq ($(FLUTTER_OS),linux)
|
ifeq ($(FLUTTER_OS),linux)
|
||||||
@mkdir -p $(INSTALL_PREFIX) $(INSTALL_DIR)
|
@mkdir -p $(INSTALL_PREFIX) $(INSTALL_DIR)
|
||||||
rm -rf $(INSTALL_PREFIX)/clide
|
rm -rf $(INSTALL_PREFIX)/clide
|
||||||
cp -a $(BUNDLE_DIR) $(INSTALL_PREFIX)/clide
|
cp -a $(BUNDLE_DIR) $(INSTALL_PREFIX)/clide
|
||||||
ln -sf $(INSTALL_PREFIX)/clide/clide $(INSTALL_DIR)/clide
|
install -m 755 $(CLIDE_CLI_BIN) $(INSTALL_DIR)/clide
|
||||||
@for size in $(ICON_SIZES); do \
|
@for size in $(ICON_SIZES); do \
|
||||||
dir=$(HOME)/.local/share/icons/hicolor/$${size}x$${size}/apps; \
|
dir=$(HOME)/.local/share/icons/hicolor/$${size}x$${size}/apps; \
|
||||||
mkdir -p $$dir; \
|
mkdir -p $$dir; \
|
||||||
@@ -177,14 +227,17 @@ ifeq ($(FLUTTER_OS),linux)
|
|||||||
> $(HOME)/.local/share/applications/net.schweitz.clide.desktop
|
> $(HOME)/.local/share/applications/net.schweitz.clide.desktop
|
||||||
@gtk-update-icon-cache -f -t $(HOME)/.local/share/icons/hicolor 2>/dev/null || true
|
@gtk-update-icon-cache -f -t $(HOME)/.local/share/icons/hicolor 2>/dev/null || true
|
||||||
@update-desktop-database $(HOME)/.local/share/applications 2>/dev/null || true
|
@update-desktop-database $(HOME)/.local/share/applications 2>/dev/null || true
|
||||||
@echo "installed: $(INSTALL_DIR)/clide -> $(INSTALL_PREFIX)/clide/clide"
|
@echo "cli: $(INSTALL_DIR)/clide (C client)"
|
||||||
|
@echo "gui: $(INSTALL_PREFIX)/clide/clide"
|
||||||
@echo "desktop: ~/.local/share/applications/net.schweitz.clide.desktop"
|
@echo "desktop: ~/.local/share/applications/net.schweitz.clide.desktop"
|
||||||
@echo "version: $(VERSION)"
|
@echo "version: $(VERSION)"
|
||||||
else ifeq ($(FLUTTER_OS),macos)
|
else ifeq ($(FLUTTER_OS),macos)
|
||||||
@mkdir -p $(HOME)/Applications
|
@mkdir -p $(HOME)/Applications $(INSTALL_DIR)
|
||||||
rm -rf $(HOME)/Applications/clide.app
|
rm -rf $(HOME)/Applications/clide.app
|
||||||
cp -a $(BUNDLE_DIR) $(HOME)/Applications/clide.app
|
cp -a $(BUNDLE_DIR) $(HOME)/Applications/clide.app
|
||||||
@echo "installed: ~/Applications/clide.app"
|
install -m 755 $(CLIDE_CLI_BIN) $(INSTALL_DIR)/clide
|
||||||
|
@echo "gui: ~/Applications/clide.app"
|
||||||
|
@echo "cli: $(INSTALL_DIR)/clide (C client)"
|
||||||
@echo "version: $(VERSION)"
|
@echo "version: $(VERSION)"
|
||||||
else
|
else
|
||||||
@echo "install not yet supported on $(FLUTTER_OS)"
|
@echo "install not yet supported on $(FLUTTER_OS)"
|
||||||
@@ -205,11 +258,14 @@ ifeq ($(FLUTTER_OS),linux)
|
|||||||
@update-desktop-database $(HOME)/.local/share/applications 2>/dev/null || true
|
@update-desktop-database $(HOME)/.local/share/applications 2>/dev/null || true
|
||||||
@echo "uninstalled"
|
@echo "uninstalled"
|
||||||
else ifeq ($(FLUTTER_OS),macos)
|
else ifeq ($(FLUTTER_OS),macos)
|
||||||
|
rm -f $(INSTALL_DIR)/clide
|
||||||
rm -rf $(HOME)/Applications/clide.app
|
rm -rf $(HOME)/Applications/clide.app
|
||||||
@echo "uninstalled"
|
@echo "uninstalled"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# -- dugite-native (bundled git) ------------------------------------------
|
# -- dugite-native (bundled git) ------------------------------------------
|
||||||
|
# Security tracking (D-59): run `make dugite-check` quarterly, or on a git CVE,
|
||||||
|
# to compare this pin against the latest upstream release. T-88 is the calendar.
|
||||||
|
|
||||||
DUGITE_VERSION := v2.53.0-3
|
DUGITE_VERSION := v2.53.0-3
|
||||||
DUGITE_COMMIT := f49d009
|
DUGITE_COMMIT := f49d009
|
||||||
@@ -241,11 +297,44 @@ dugite-fetch: ## Download and extract the dugite-native git distribution.
|
|||||||
dugite-clean: ## Remove the dugite-native directory.
|
dugite-clean: ## Remove the dugite-native directory.
|
||||||
rm -rf $(DUGITE_DIR)
|
rm -rf $(DUGITE_DIR)
|
||||||
|
|
||||||
|
# -- clide-cli ----------------------------------------------------------
|
||||||
|
# The C `clide` shell client that talks to the in-process IPC server
|
||||||
|
# (T-99 / T-126). One source file, no third-party deps; the build
|
||||||
|
# target picks up whatever `cc` is on PATH.
|
||||||
|
|
||||||
|
CLIDE_CLI_SRC := native/clide-cli/clide.c
|
||||||
|
ifeq ($(FLUTTER_OS),windows)
|
||||||
|
CLIDE_CLI_BIN := native/windows-x64/clide.exe
|
||||||
|
else
|
||||||
|
CLIDE_CLI_BIN := native/$(if $(filter Darwin,$(shell uname -s)),macos,linux)-$(shell uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/')/clide
|
||||||
|
endif
|
||||||
|
CC ?= cc
|
||||||
|
|
||||||
|
.PHONY: clide-cli
|
||||||
|
clide-cli: $(CLIDE_CLI_BIN) ## Compile the C `clide` shell client.
|
||||||
|
|
||||||
|
$(CLIDE_CLI_BIN): $(CLIDE_CLI_SRC)
|
||||||
|
@mkdir -p $(dir $(CLIDE_CLI_BIN))
|
||||||
|
ifeq ($(FLUTTER_OS),windows)
|
||||||
|
ci/build_cli_windows.sh
|
||||||
|
else
|
||||||
|
$(CC) -std=c99 -O2 -Wall -Wextra -o $(CLIDE_CLI_BIN) $(CLIDE_CLI_SRC)
|
||||||
|
endif
|
||||||
|
@echo "==> built $(CLIDE_CLI_BIN)"
|
||||||
|
|
||||||
|
.PHONY: clide-cli-clean
|
||||||
|
clide-cli-clean: ## Remove the compiled C `clide` client.
|
||||||
|
rm -f $(CLIDE_CLI_BIN)
|
||||||
|
|
||||||
# -- security -------------------------------------------------------------
|
# -- security -------------------------------------------------------------
|
||||||
|
|
||||||
.PHONY: security
|
.PHONY: security
|
||||||
security: ## Dart advisory review.
|
security: ## Supply-chain gate — osv-scanner over pubspec.lock (CI PR-merge pipeline; run locally on demand). Fails on a known advisory.
|
||||||
@echo "security: Dart advisories reviewed manually before pubspec.yaml bumps."
|
ci/osv_scan.sh
|
||||||
|
|
||||||
|
.PHONY: dugite-check
|
||||||
|
dugite-check: ## Track dugite-native (bundled git) upstream releases for security drift (T-88 / D-59). Run quarterly, or on a git CVE. Informational, not a gate.
|
||||||
|
ci/check_dugite_version.sh
|
||||||
|
|
||||||
# -- pre-push gate --------------------------------------------------------
|
# -- pre-push gate --------------------------------------------------------
|
||||||
|
|
||||||
@@ -254,10 +343,14 @@ decisions-validate: ## Parser dry-run over governance/{decisions,questions,rejec
|
|||||||
pql decisions validate
|
pql decisions validate
|
||||||
|
|
||||||
.PHONY: push-check
|
.PHONY: push-check
|
||||||
push-check: decisions-validate test-core test test-a11y coverage-gate changelog-gate ## Pre-push gate (fast — <2 min target).
|
# NOTE: the `security` (osv-scanner) gate is deliberately NOT in push-check —
|
||||||
|
# it runs in the CI PR-merge pipeline (where the scanner is provisioned) so we
|
||||||
|
# don't force every dev machine to install osv-scanner. Run it locally any time
|
||||||
|
# with `make security`.
|
||||||
|
push-check: decisions-validate changelog-gate test-coverage coverage-gate test-core ## Pre-push gate (fast — <2 min target). Order is fail-fast: instant gates (decisions, changelog) first, then the coverage suite + gate (the expensive, most-likely-to-fail stage) BEFORE test-core — a coverage miss aborts here instead of after running everything, so a fix doesn't force a full re-run of the rest. test-coverage already runs the a11y suite (test/a11y), so no separate test-a11y pass.
|
||||||
|
|
||||||
.PHONY: push-check-full
|
.PHONY: push-check-full
|
||||||
push-check-full: push-check test-integration smoke-bundle ## Pre-release gate (push-check + integration + smoke; slower; skips theme_picker per T-116).
|
push-check-full: push-check test-integration smoke-bundle ## Pre-release gate (push-check + integration + smoke; slower).
|
||||||
|
|
||||||
.PHONY: hooks
|
.PHONY: hooks
|
||||||
hooks: ## Install the repo's git hooks.
|
hooks: ## Install the repo's git hooks.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This document governs what clide is allowed to do at runtime, what it's allowed to depend on, and how contributors — human and agent — introduce code into the project. It is binding on all contributors. When in doubt, stop and ask.
|
This document governs what clide is allowed to do at runtime, what it's allowed to depend on, and how contributors — human and agent — introduce code into the project. It is binding on all contributors. When in doubt, stop and ask.
|
||||||
|
|
||||||
Rationale for specific architectural choices referenced here and in code comments (the D-### markers) lives in `decisions/`. This document sets the rules; `decisions/` records why the rules produced the code they did in a given case. If the two ever disagree, the rule in this document wins until the document itself is changed.
|
Rationale for specific architectural choices referenced here and in code comments (the D-### markers) lives in `governance/decisions/`. This document sets the rules; `governance/decisions/` records why the rules produced the code they did in a given case. If the two ever disagree, the rule in this document wins until the document itself is changed.
|
||||||
|
|
||||||
## Why this document exists
|
## Why this document exists
|
||||||
|
|
||||||
@@ -124,9 +124,9 @@ When removing a dependency:
|
|||||||
|
|
||||||
1. **Grep the entire repository** for references to the package, its exports, and any type names it contributed. `rg '<package>|<PackageType>|<prefix_>'` across the repo. Zero hits outside git history is the goal. A single lingering import will break the build; a single lingering FFI stub or type alias will compile fine and fail at runtime.
|
1. **Grep the entire repository** for references to the package, its exports, and any type names it contributed. `rg '<package>|<PackageType>|<prefix_>'` across the repo. Zero hits outside git history is the goal. A single lingering import will break the build; a single lingering FFI stub or type alias will compile fine and fail at runtime.
|
||||||
2. **Regenerate the lockfile** as part of the same PR. A `pubspec.yaml` with the dep removed but a `pubspec.lock` that still pins it is a partial removal, and CI or a fresh clone will happily continue installing the package.
|
2. **Regenerate the lockfile** as part of the same PR. A `pubspec.yaml` with the dep removed but a `pubspec.lock` that still pins it is a partial removal, and CI or a fresh clone will happily continue installing the package.
|
||||||
3. **Update `app/assets/licenses.yaml`** to drop the removed package and any transitive deps it brought in that aren't pulled by anything else. If the license manifest is auto-generated on release, verify the generation script sees the change; if it's maintained by hand, edit it in the same PR.
|
3. **Update `assets/licenses.yaml`** to drop the removed package and any transitive deps it brought in that aren't pulled by anything else. If the license manifest is auto-generated on release, verify the generation script sees the change; if it's maintained by hand, edit it in the same PR.
|
||||||
4. **Remove any vendored artifacts** tied to the dep — binaries, prebuilt assets, generated bindings — and delete their `BUILD.md` records. An orphaned vendored binary is worse than a removed one because it looks legitimate.
|
4. **Remove any vendored artifacts** tied to the dep — binaries, prebuilt assets, generated bindings — and delete their `BUILD.md` records. An orphaned vendored binary is worse than a removed one because it looks legitimate.
|
||||||
5. **Check for architectural assumptions** that the dep was carrying. If the removed package was the thing that justified a specific data flow, build step, or platform strategy, either the replacement picks up those responsibilities or the architecture has actually changed and the relevant design decision (see `decisions/`) needs updating.
|
5. **Check for architectural assumptions** that the dep was carrying. If the removed package was the thing that justified a specific data flow, build step, or platform strategy, either the replacement picks up those responsibilities or the architecture has actually changed and the relevant design decision (see `governance/decisions/`) needs updating.
|
||||||
|
|
||||||
A dependency is not removed until all five are true. "I deleted the line from pubspec.yaml" is the start of the removal, not the end.
|
A dependency is not removed until all five are true. "I deleted the line from pubspec.yaml" is the start of the removal, not the end.
|
||||||
|
|
||||||
@@ -188,18 +188,18 @@ When in doubt about a license, the dependency does not land until the question i
|
|||||||
|
|
||||||
### Attribution requirements
|
### Attribution requirements
|
||||||
|
|
||||||
- The license manifest at `app/assets/licenses.yaml` lists every dependency with its license, copyright notice, and upstream URL.
|
- The license manifest at `assets/licenses.yaml` lists every dependency with its license, copyright notice, and upstream URL.
|
||||||
- Transitive dependencies are listed, not just direct ones. If `wasm_run` pulls in `wasmtime` which pulls in `cranelift`, all three appear.
|
- Transitive dependencies are listed, not just direct ones. If `wasm_run` pulls in `wasmtime` which pulls in `cranelift`, all three appear.
|
||||||
- Apache-2.0 dependencies get their `NOTICE` file content preserved verbatim, not summarized.
|
- Apache-2.0 dependencies get their `NOTICE` file content preserved verbatim, not summarized.
|
||||||
- Apache-2.0-with-LLVM-exception (e.g., Cranelift, parts of LLVM) requires the LLVM exception text specifically, not just the Apache-2.0 boilerplate.
|
- Apache-2.0-with-LLVM-exception (e.g., Cranelift, parts of LLVM) requires the LLVM exception text specifically, not just the Apache-2.0 boilerplate.
|
||||||
- Fonts and icon sets get attributed even if the license doesn't strictly require it. It's the right thing to do.
|
- Fonts and icon sets get attributed even if the license doesn't strictly require it. It's the right thing to do.
|
||||||
- `app/assets/licenses.yaml` is regenerated as part of the release build, not maintained by hand. A release that ships a stale manifest is a release defect.
|
- `assets/licenses.yaml` is regenerated as part of the release build, not maintained by hand. A release that ships a stale manifest is a release defect.
|
||||||
|
|
||||||
Adding a dependency means updating the license manifest in the same PR. No exceptions.
|
Adding a dependency means updating the license manifest in the same PR. No exceptions.
|
||||||
|
|
||||||
## Changelog and commit conventions
|
## Changelog and commit conventions
|
||||||
|
|
||||||
clide follows [Keep a Changelog 1.1](https://keepachangelog.com/en/1.1.0/) for `CHANGELOG.md` and [Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages. Enforcement is handled by the project's git skill; this section exists so human contributors know the standard before their first PR, and so the connection between these conventions and the rest of the policy is explicit.
|
clide follows [Keep a Changelog 1.1](https://keepachangelog.com/en/1.1.0/) for `CHANGELOG.md` and [Conventional Commits 1.0](https://www.conventionalcommits.org/en/v1.0.0/) for commit messages (see [D-37](governance/decisions/process.md#d-37)). Enforcement is handled by the project's git skill; this section exists so human contributors know the standard before their first PR, and so the connection between these conventions and the rest of the policy is explicit.
|
||||||
|
|
||||||
Security-relevant changes — CVE responses, dependency-driven vulnerability fixes, the removal of a phoning-home transitive dep, anything where the rules in this document were the reason for the change — go under the `Security` heading of the release's changelog entry, regardless of whether the code change itself looks security-shaped. That heading is the trail future-us follows to reconstruct why a dep was bumped or removed. Lumping security fixes under `Fixed` because the diff looks like a normal bug fix loses that signal and is the wrong choice even when it's technically accurate.
|
Security-relevant changes — CVE responses, dependency-driven vulnerability fixes, the removal of a phoning-home transitive dep, anything where the rules in this document were the reason for the change — go under the `Security` heading of the release's changelog entry, regardless of whether the code change itself looks security-shaped. That heading is the trail future-us follows to reconstruct why a dep was bumped or removed. Lumping security fixes under `Fixed` because the diff looks like a normal bug fix loses that signal and is the wrong choice even when it's technically accurate.
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
# clide
|
# clide
|
||||||
|
|
||||||
An IDE for Claude Code CLI. Native rendering, terminal-first interaction, pql-powered queries, canvas and graph surfaces. Linux and macOS.
|
An IDE for Claude Code CLI. Native rendering, terminal-first interaction, pql-powered queries, canvas and graph surfaces. Linux, macOS and Windows.
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
Single Flutter package at the repo root. The app hosts everything in-process: IPC server, subsystem handlers (pane, files, editor, git, pql), and the extension framework. tmux owns Claude session persistence (D-41).
|
Single Flutter package at the repo root. The app hosts everything in-process: IPC server, subsystem handlers (pane, files, editor, git, pql), and the extension framework. Claude session persistence is `--resume <session-id>` against Claude Code's transcript files (D-77, superseding the tmux-backed D-41).
|
||||||
|
|
||||||
- **`lib/`** — all Dart code. Core subsystems (`lib/src/`), kernel services (`lib/kernel/`), UI widgets (`lib/widgets/`), built-in extensions (`lib/builtin/`), the extension framework (`lib/extension/`).
|
- **`lib/`** — all Dart code. Core subsystems (`lib/src/`), kernel services (`lib/kernel/`), UI widgets (`lib/widgets/`), built-in extensions (`lib/builtin/`), the extension framework (`lib/extension/`).
|
||||||
- **PTY** — `lib/src/pty/` spawns child processes via Dart FFI `posix_openpt()` + `posix_spawn()` directly; no external helper binary.
|
- **PTY** — `lib/src/pty/` spawns child processes via Dart FFI `posix_openpt()` + `posix_spawn()` directly; no external helper binary.
|
||||||
@@ -15,14 +15,18 @@ Claude drives the UI through a `clide` CLI surface (Bash, not MCP). Every CLI su
|
|||||||
|
|
||||||
## Built-in extensions
|
## Built-in extensions
|
||||||
|
|
||||||
canvas, claude, claude_control, decisions, diff, editor, extensions_ui, files, git, graph, grammars_core, ipc_status, keybindings_ui, markdown, pql, problems, settings_ui, terminal, theme_picker, tickets, todos, welcome.
|
canvas, claude, claude_control, cli_install, decisions, deeplink, default_layout, diff, editor, extensions_ui, files, git, grammars_core, graph, ipc_status, keybindings_ui, markdown, menubar, output, pql, problems, search, settings_ui, terminal, theme_picker, tickets, todos, view, vim, welcome.
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
Requires Flutter (stable channel) on the host. One-time setup:
|
Requires Flutter (stable channel) and [pql](https://github.com/postmeridiem/pql)
|
||||||
|
on the host. pql is a hard dependency — the pre-push gate runs `pql decisions
|
||||||
|
validate` and the governance + ticket workflow is built on it (see its repo for
|
||||||
|
install). One-time setup:
|
||||||
|
|
||||||
```
|
```
|
||||||
make hooks && flutter pub get
|
make hooks && flutter pub get
|
||||||
|
pql init # once, in the repo root — wires up the pql skill + perms
|
||||||
```
|
```
|
||||||
|
|
||||||
Then:
|
Then:
|
||||||
@@ -40,7 +44,7 @@ make push-check # pre-push gate: decisions + core + fast + a11y + coverage
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
Pre-v2.0 (`2.0.0-dev`). Interaction model and panel system landed. The Python Textual v1.2.0 predecessor is archived under [`legacy/`](https://github.com/postmeridiem/clide/tree/main/legacy).
|
Active development; the interaction model, panel system, and settings engine have landed. The Python Textual predecessor is archived under [`legacy/`](https://github.com/postmeridiem/clide/tree/main/legacy).
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright (c) 2012-2013, The Mozilla Corporation and Telefonica S.A.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter)
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
https://openfontlicense.org
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Canvas" },
|
||||||
|
"empty": { "translation": "Open a .canvas file to view it here." },
|
||||||
|
"status.loading": { "translation": "Loading…" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Claude" },
|
||||||
|
"status.attaching": { "translation": "attaching…" },
|
||||||
|
"status.no-tmux": { "translation": "no-tmux · fresh every launch" },
|
||||||
|
"status.exited": { "translation": "session exited" },
|
||||||
|
"status.primary-exited": { "translation": "session exited — restart clide to retry" },
|
||||||
|
"banner.title": { "translation": "Claude" },
|
||||||
|
"banner.warmingUp": { "translation": "Warming up — your conversation will appear here." },
|
||||||
|
"banner.role.primary": { "translation": "primary" },
|
||||||
|
"banner.role.secondary": { "translation": "session {index}" },
|
||||||
|
"composer.hint": { "translation": "Message Claude… (Enter to send · Shift+Enter for newline)" },
|
||||||
|
"composer.stop": { "translation": "Stop ⎋" },
|
||||||
|
"composer.stop.hint": { "translation": "Interrupt the running turn (Escape)" },
|
||||||
|
"composer.removeAttachment": { "translation": "Remove {name}" },
|
||||||
|
"pane.title.primary": { "translation": "claude — primary" },
|
||||||
|
"pane.title.secondary": { "translation": "claude — secondary {index}" },
|
||||||
|
"pane.starting": { "translation": "starting…" },
|
||||||
|
"pane.modeBadge.semantics": { "translation": "permission mode: {mode}" },
|
||||||
|
"running.semantics": { "translation": "Claude is running" },
|
||||||
|
"running.verb.pondering": { "translation": "Pondering" },
|
||||||
|
"running.verb.conjuring": { "translation": "Conjuring" },
|
||||||
|
"running.verb.brewing": { "translation": "Brewing" },
|
||||||
|
"running.verb.tinkering": { "translation": "Tinkering" },
|
||||||
|
"running.verb.noodling": { "translation": "Noodling" },
|
||||||
|
"running.verb.percolating": { "translation": "Percolating" },
|
||||||
|
"running.verb.computing": { "translation": "Computing" },
|
||||||
|
"running.verb.wrangling": { "translation": "Wrangling" },
|
||||||
|
"running.verb.untangling": { "translation": "Untangling" },
|
||||||
|
"running.verb.synthesizing": { "translation": "Synthesizing" },
|
||||||
|
"running.verb.cogitating": { "translation": "Cogitating" },
|
||||||
|
"running.verb.whirring": { "translation": "Whirring" },
|
||||||
|
"running.verb.mincing": { "translation": "Mincing" },
|
||||||
|
"running.verb.boiling": { "translation": "Boiling" },
|
||||||
|
"running.verb.humming": { "translation": "Humming" },
|
||||||
|
"running.verb.buzzing": { "translation": "Buzzing" },
|
||||||
|
"running.verb.magicking": { "translation": "Magicking" },
|
||||||
|
"running.verb.cliding": { "translation": "Cliding" },
|
||||||
|
"running.verb.zooming": { "translation": "Zooming" },
|
||||||
|
"running.verb.bouncing": { "translation": "Bouncing" },
|
||||||
|
"conversation.empty": { "translation": "Waiting for Claude…" },
|
||||||
|
"conversation.label.you": { "translation": "you" },
|
||||||
|
"conversation.label.claude": { "translation": "claude" },
|
||||||
|
"conversation.label.clide": { "translation": "clide" },
|
||||||
|
"conversation.label.agent": { "translation": "agent" },
|
||||||
|
"conversation.label.agentPrompt": { "translation": "agent prompt" },
|
||||||
|
"conversation.label.context": { "translation": "context" },
|
||||||
|
"conversation.label.thinking": { "translation": "thinking" },
|
||||||
|
"conversation.label.agentThinking": { "translation": "agent thinking" },
|
||||||
|
"conversation.label.image": { "translation": "image" },
|
||||||
|
"conversation.label.icon": { "translation": "icons" },
|
||||||
|
"conversation.label.drawing": { "translation": "drawing" },
|
||||||
|
"conversation.draw.viewSource": { "translation": "view d2 source" },
|
||||||
|
"conversation.label.agentRun": { "translation": "agent run" },
|
||||||
|
"conversation.label.workflow": { "translation": "workflow" },
|
||||||
|
"conversation.label.error": { "translation": "error" },
|
||||||
|
"conversation.label.result": { "translation": "result" },
|
||||||
|
"conversation.label.denied": { "translation": "denied" },
|
||||||
|
"conversation.segment.prompt": { "translation": "prompt" },
|
||||||
|
"conversation.segment.result": { "translation": "result" },
|
||||||
|
"conversation.segment.liveTail": { "translation": "live tail" },
|
||||||
|
"conversation.segment.usage": { "translation": "usage" },
|
||||||
|
"conversation.segment.script": { "translation": "script" },
|
||||||
|
"conversation.workflow.launching": { "translation": "Launching…" },
|
||||||
|
"conversation.imagePlaceholder": { "translation": "could not load {path}" },
|
||||||
|
"conversation.bashTail.empty": { "translation": "no independent source to follow" },
|
||||||
|
"conversation.bashTail.label": { "translation": "live tail" },
|
||||||
|
"conversation.cluster.activity": { "translation": "Activity" },
|
||||||
|
"conversation.cluster.edits": { "translation": "Edits" },
|
||||||
|
"conversation.counter.step": { "translation": "1 step" },
|
||||||
|
"conversation.counter.steps": { "translation": "{count} steps" },
|
||||||
|
"conversation.counter.edit": { "translation": "1 edit" },
|
||||||
|
"conversation.counter.edits": { "translation": "{count} edits" },
|
||||||
|
"conversation.counter.starting": { "translation": "starting" },
|
||||||
|
"conversation.counter.agents": { "translation": "{done}/{total} agents" },
|
||||||
|
"prompt.permission.allow": { "translation": "1. Allow" },
|
||||||
|
"prompt.permission.allowRemember": { "translation": "2. Allow & don't ask again" },
|
||||||
|
"prompt.permission.deny": { "translation": "{n}. Deny" },
|
||||||
|
"prompt.permission.denySimplify": { "translation": "{n}. Deny & simplify" },
|
||||||
|
"prompt.permission.denySimplify.tooltip": { "translation": "Deny and ask Claude to retry this action in a simpler format — complex interactions don't work well with the permission system." },
|
||||||
|
"prompt.permission.note.placeholder": { "translation": "add a note (optional) — sent to Claude" },
|
||||||
|
"prompt.permission.label": { "translation": "permission · {name}" },
|
||||||
|
"prompt.question.label": { "translation": "question" },
|
||||||
|
"prompt.review.label": { "translation": "review" },
|
||||||
|
"prompt.review.title": { "translation": "Review your answers" },
|
||||||
|
"prompt.submit": { "translation": "Submit" },
|
||||||
|
"prompt.submitAnswers": { "translation": "Submit answers" },
|
||||||
|
"prompt.back": { "translation": "‹ Back" },
|
||||||
|
"prompt.next": { "translation": "Next ›" },
|
||||||
|
"prompt.reviewNav": { "translation": "Review ›" },
|
||||||
|
"prompt.nav.review": { "translation": "Review" },
|
||||||
|
"prompt.option.other": { "translation": "Other…" },
|
||||||
|
"prompt.other.placeholder": { "translation": "type your answer…" },
|
||||||
|
"prompt.note.placeholder": { "translation": "+ note (optional)" },
|
||||||
|
"prompt.chatInstead": { "translation": "chat instead" },
|
||||||
|
"tool.edit.before": { "translation": "— before" },
|
||||||
|
"tool.edit.after": { "translation": "+ after" },
|
||||||
|
"tool.bash.background": { "translation": "background" },
|
||||||
|
"tool.name.Read": { "translation": "Read" },
|
||||||
|
"tool.name.Edit": { "translation": "Edit" },
|
||||||
|
"tool.name.MultiEdit": { "translation": "MultiEdit" },
|
||||||
|
"tool.name.Write": { "translation": "Write" },
|
||||||
|
"tool.name.NotebookEdit": { "translation": "NotebookEdit" },
|
||||||
|
"tool.name.WebFetch": { "translation": "WebFetch" },
|
||||||
|
"tool.name.WebSearch": { "translation": "WebSearch" },
|
||||||
|
"tool.name.Task": { "translation": "Task" },
|
||||||
|
"tool.name.TodoWrite": { "translation": "TodoWrite" },
|
||||||
|
"tool.name.ExitPlanMode": { "translation": "ExitPlanMode" },
|
||||||
|
"permissionControl.semantics": { "translation": "permission mode: {mode}. Activate to change." },
|
||||||
|
"permissionControl.tooltip": { "translation": "Permission mode: {mode} — change (Ctrl/Cmd+M cycles; +Shift includes bypass)" },
|
||||||
|
"permissionControl.bypassHint": { "translation": "shift-click" },
|
||||||
|
"permissionControl.bypassSemantics": { "translation": "bypassPermissions — shift-click to enable" },
|
||||||
|
"permissionBadge.tooltip": { "translation": "Permission mode: {mode}. Click to cycle default/acceptEdits/plan; Shift-click for bypassPermissions." },
|
||||||
|
"permissionBadge.semantics": { "translation": "Permission mode: {label}" },
|
||||||
|
"card.expand": { "translation": "Expand" },
|
||||||
|
"card.collapse": { "translation": "Collapse" },
|
||||||
|
"card.succeeded": { "translation": "succeeded" },
|
||||||
|
"card.failed": { "translation": "failed" },
|
||||||
|
"card.copy": { "translation": "copy" },
|
||||||
|
"taskDock.summary": { "translation": "{count} {tasks} · {done} done" },
|
||||||
|
"taskDock.task.singular": { "translation": "task" },
|
||||||
|
"taskDock.task.plural": { "translation": "tasks" },
|
||||||
|
"taskDock.collapse": { "translation": "Collapse tasks" },
|
||||||
|
"taskDock.expand": { "translation": "Expand tasks" },
|
||||||
|
"taskDock.semantics": { "translation": "Claude task list, {summary}, {state}" },
|
||||||
|
"taskDock.state.expanded": { "translation": "expanded" },
|
||||||
|
"taskDock.state.collapsed": { "translation": "collapsed" },
|
||||||
|
"taskDock.status.done": { "translation": "done" },
|
||||||
|
"taskDock.status.inProgress": { "translation": "in progress" },
|
||||||
|
"taskDock.status.pending": { "translation": "pending" },
|
||||||
|
"taskDock.row.semantics": { "translation": "{text}, {status}" },
|
||||||
|
"sessionPicker.title": { "translation": "Resume a Claude session" },
|
||||||
|
"sessionPicker.empty": { "translation": "No sessions found for this workspace." },
|
||||||
|
"modelPicker.cancel": { "translation": "cancel" },
|
||||||
|
"image.semantics": { "translation": "Image {name}" },
|
||||||
|
"activity.section.session": { "translation": "SESSION" },
|
||||||
|
"activity.control.clear": { "translation": "clear" },
|
||||||
|
"activity.control.compact": { "translation": "compact" },
|
||||||
|
"activity.control.fork": { "translation": "fork" },
|
||||||
|
"activity.control.resume": { "translation": "resume" },
|
||||||
|
"activity.control.refreshUsage": { "translation": "refresh usage" },
|
||||||
|
"activity.control.semantics": { "translation": "{label} session" },
|
||||||
|
"activity.control.tooltip": { "translation": "{label} · {command}" },
|
||||||
|
"activity.empty": { "translation": "No activity recorded yet." },
|
||||||
|
"activity.section.workflows": { "translation": "WORKFLOWS" },
|
||||||
|
"activity.workflow.fallback": { "translation": "workflow" },
|
||||||
|
"activity.workflow.done": { "translation": "done" },
|
||||||
|
"activity.workflow.starting": { "translation": "starting" },
|
||||||
|
"activity.section.usage": { "translation": "USAGE" },
|
||||||
|
"activity.row.session": { "translation": "session" },
|
||||||
|
"activity.row.weekAll": { "translation": "week (all)" },
|
||||||
|
"activity.row.weekSonnet": { "translation": "week (sonnet)" },
|
||||||
|
"activity.section.today": { "translation": "TODAY" },
|
||||||
|
"activity.row.messages": { "translation": "messages" },
|
||||||
|
"activity.row.sessions": { "translation": "sessions" },
|
||||||
|
"activity.row.toolCalls": { "translation": "tool calls" },
|
||||||
|
"activity.section.lifetime": { "translation": "LIFETIME" },
|
||||||
|
"activity.section.runtime": { "translation": "RUNTIME · primary" },
|
||||||
|
"activity.row.model": { "translation": "model" },
|
||||||
|
"activity.row.effort": { "translation": "effort" },
|
||||||
|
"activity.row.context": { "translation": "context" },
|
||||||
|
"activity.row.mode": { "translation": "mode" },
|
||||||
|
"activity.row.skills": { "translation": "skills" },
|
||||||
|
"config.empty": { "translation": "Claude environment not loaded." },
|
||||||
|
"config.section.settings": { "translation": "SETTINGS" },
|
||||||
|
"config.row.model": { "translation": "model" },
|
||||||
|
"config.row.effort": { "translation": "effort" },
|
||||||
|
"config.row.permissionMode": { "translation": "permission mode" },
|
||||||
|
"config.row.outputStyle": { "translation": "output style" },
|
||||||
|
"config.row.source": { "translation": "source" },
|
||||||
|
"config.row.source.value": { "translation": "~/.claude + .claude" },
|
||||||
|
"config.footer": { "translation": "expand a list to see all · click a skill/agent/command → opens its .md" },
|
||||||
|
"config.section.skills": { "translation": "SKILLS" },
|
||||||
|
"config.section.agents": { "translation": "AGENTS" },
|
||||||
|
"config.section.commands": { "translation": "COMMANDS" },
|
||||||
|
"config.section.hooks": { "translation": "HOOKS" },
|
||||||
|
"config.section.permissions": { "translation": "PERMISSIONS" },
|
||||||
|
"config.section.mcpServers": { "translation": "MCP SERVERS" },
|
||||||
|
"config.perm.allow": { "translation": "allow" },
|
||||||
|
"config.perm.ask": { "translation": "ask" },
|
||||||
|
"config.perm.deny": { "translation": "deny" },
|
||||||
|
"config.control.semantics": { "translation": "{label}: {value}. Click to change." },
|
||||||
|
"config.control.tooltip": { "translation": "change {label}" },
|
||||||
|
"config.control.option.semantics": { "translation": "{label}: {name}" },
|
||||||
|
"roster.bypass.confirmBody": { "translation": "Enable bypassPermissions? All tool calls will be auto-allowed." },
|
||||||
|
"roster.bypass.confirm.semantics": { "translation": "Confirm bypass" },
|
||||||
|
"roster.bypass.confirm.tooltip": { "translation": "Confirm" },
|
||||||
|
"roster.bypass.ok": { "translation": "OK" },
|
||||||
|
"roster.bypass.cancel.semantics": { "translation": "Cancel bypass" },
|
||||||
|
"roster.bypass.cancel.tooltip": { "translation": "Cancel" },
|
||||||
|
"roster.bypass.cancel": { "translation": "Cancel" },
|
||||||
|
"roster.hidePane": { "translation": "Hide pane" },
|
||||||
|
"roster.showPane": { "translation": "Show pane" },
|
||||||
|
"roster.unmute": { "translation": "Unmute messages" },
|
||||||
|
"roster.mute": { "translation": "Mute messages" },
|
||||||
|
"roster.inject": { "translation": "Inject message" },
|
||||||
|
"roster.fork": { "translation": "Fork session" },
|
||||||
|
"roster.close": { "translation": "Close session" },
|
||||||
|
"roster.inject.cancel": { "translation": "Cancel" },
|
||||||
|
"taskRow.reassign": { "translation": "Reassign task" },
|
||||||
|
"team.empty": { "translation": "No team active." },
|
||||||
|
"team.section.tasks": { "translation": "TASKS" },
|
||||||
|
"tabStrip.activity": { "translation": "Activity" },
|
||||||
|
"tabStrip.team": { "translation": "Team" },
|
||||||
|
"tabStrip.team.count": { "translation": "Team · {count}" },
|
||||||
|
"tabStrip.config": { "translation": "Config" },
|
||||||
|
"teamChat.section.messages": { "translation": "MESSAGES" },
|
||||||
|
"teamChat.popOut.semantics": { "translation": "Open full chat pane" },
|
||||||
|
"teamChat.popOut.tooltip": { "translation": "Open full chat" },
|
||||||
|
"teamChat.empty": { "translation": "No messages yet." },
|
||||||
|
"teamChat.composer.placeholder": { "translation": "@name or @team …" },
|
||||||
|
"teamChat.pane.title": { "translation": "Team Chat" },
|
||||||
|
"teamChat.interrupt.semantics": { "translation": "Interrupt target session" },
|
||||||
|
"teamChat.interrupt.label": { "translation": "Interrupt" },
|
||||||
|
"command.newSecondary": { "translation": "Claude: open a secondary session" },
|
||||||
|
"command.killAllSessions": { "translation": "Claude: kill all sessions for this repo" },
|
||||||
|
"command.sessionStorage": { "translation": "Claude: session storage (disk usage + cleanup)" },
|
||||||
|
"command.activity.foldLevel": { "translation": "Claude: cycle activity fold level" },
|
||||||
|
"command.agent.show": { "translation": "Claude: show an agent session pane" },
|
||||||
|
"command.agent.hide": { "translation": "Claude: hide an agent session pane" },
|
||||||
|
"command.agent.close": { "translation": "Claude: close (kill) an agent session" },
|
||||||
|
"command.agent.mute": { "translation": "Claude: mute broker delivery to an agent session" },
|
||||||
|
"command.agent.unmute": { "translation": "Claude: unmute broker delivery to an agent session" },
|
||||||
|
"command.agent.injectMessage": { "translation": "Claude: inject a text turn into an agent session" },
|
||||||
|
"command.agent.setPermissionMode": { "translation": "Claude: set permission mode for an agent session" },
|
||||||
|
"command.mode.cycle": { "translation": "Claude: Cycle permission mode" },
|
||||||
|
"command.task.reassign": { "translation": "Claude: reassign a shared task to an agent" },
|
||||||
|
"command.teamChat.open": { "translation": "Claude: open the team chat pane" },
|
||||||
|
"command.teamChat.post": { "translation": "Claude: post a message into the team channel as the user" },
|
||||||
|
"command.agent.fork": { "translation": "Claude: fork a managed session into a new branch session" },
|
||||||
|
"settings.activity.title": { "translation": "Activity" },
|
||||||
|
"settings.activity.conversation.label": { "translation": "Conversation" },
|
||||||
|
"settings.activity.foldLevel.label": { "translation": "Fold level" },
|
||||||
|
"settings.activity.foldLevel.help": { "translation": "How aggressively the conversation folds tool calls, thinking, and results." },
|
||||||
|
"settings.activity.opt.none": { "translation": "Show everything" },
|
||||||
|
"settings.activity.opt.tools": { "translation": "Fold tool calls" },
|
||||||
|
"settings.activity.opt.thinking": { "translation": "Fold tools + thinking" },
|
||||||
|
"settings.activity.opt.everything": { "translation": "Fold all but prose" },
|
||||||
|
"settings.claude.title": { "translation": "Claude" },
|
||||||
|
"settings.claude.newSessionDefaults.label": { "translation": "New session defaults" },
|
||||||
|
"settings.claude.model.label": { "translation": "Model" },
|
||||||
|
"settings.claude.model.help": { "translation": "Model for new sessions." },
|
||||||
|
"settings.claude.effort.label": { "translation": "Effort" },
|
||||||
|
"settings.claude.effort.help": { "translation": "Reasoning effort for new sessions (applied via --effort at spawn)." },
|
||||||
|
"settings.claude.permissionMode.label": { "translation": "Permission mode" },
|
||||||
|
"settings.claude.permissionMode.help": { "translation": "Starting permission mode for new sessions." },
|
||||||
|
"settings.claude.account.label": { "translation": "Account" },
|
||||||
|
"settings.claude.account.registry.label": { "translation": "Accounts" },
|
||||||
|
"settings.claude.account.registry.help": { "translation": "Registered Claude accounts (each a separate config dir + login)." },
|
||||||
|
"settings.claude.account.workspace.label": { "translation": "Account for this workspace" },
|
||||||
|
"settings.claude.account.workspace.help": { "translation": "Which Claude account this repo runs under; Default uses the system login." }
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"command.clide.installCli": { "translation": "clide: Install 'clide' command in PATH" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Decisions" },
|
||||||
|
"tab.detail.title": { "translation": "Decision" },
|
||||||
|
"loading": { "translation": "Loading decisions..." },
|
||||||
|
"error.load": { "translation": "failed to load decisions" },
|
||||||
|
"empty": { "translation": "No decisions found.\nRun `pql decisions sync` to index." },
|
||||||
|
"filter.hint": { "translation": "Filter decisions…" },
|
||||||
|
"refresh.tooltip": { "translation": "Refresh decisions" },
|
||||||
|
"section.confirmed": { "translation": "CONFIRMED" },
|
||||||
|
"section.questions": { "translation": "QUESTIONS" },
|
||||||
|
"section.rejected": { "translation": "REJECTED" },
|
||||||
|
"badge.resolved": { "translation": "resolved" },
|
||||||
|
"detail.loading": { "translation": "Loading…" },
|
||||||
|
"detail.empty": { "translation": "Select a decision to view details." },
|
||||||
|
"detail.section.refs": { "translation": "CROSS-REFERENCES" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"dialog.title": { "translation": "Open an external link?" },
|
||||||
|
"dialog.body": { "translation": "A clide:// link from outside the app is asking to:" },
|
||||||
|
"dialog.warning": { "translation": "Only allow this if you trust where the link came from." },
|
||||||
|
"button.cancel": { "translation": "Cancel" },
|
||||||
|
"button.open": { "translation": "Open" },
|
||||||
|
"command.deeplink.invoke": { "translation": "Open a clide:// deep link" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"command.reset": { "translation": "Layout: Reset to Classic" },
|
||||||
|
"preset.classic": { "translation": "Classic" },
|
||||||
|
"command.palette.toggle": { "translation": "Command Palette" },
|
||||||
|
"command.sidebar.collapse": { "translation": "Toggle Sidebar Collapse" },
|
||||||
|
"command.context.collapse": { "translation": "Toggle Context Panel Collapse" },
|
||||||
|
"command.panel.focus.left": { "translation": "Focus Left Panel" },
|
||||||
|
"command.panel.focus.middle": { "translation": "Focus Middle Panel" },
|
||||||
|
"command.panel.focus.right": { "translation": "Focus Right Panel" },
|
||||||
|
"command.panel.focusMode": { "translation": "Toggle Focus Mode" },
|
||||||
|
"command.panel.focusMode.exit": { "translation": "Exit Focus Mode" },
|
||||||
|
"command.editor.open": { "translation": "Open Editor" },
|
||||||
|
"command.editor.close": { "translation": "Close Editor" },
|
||||||
|
"command.workspace.tab.next": { "translation": "Next Workspace Tab" },
|
||||||
|
"command.workspace.tab.previous": { "translation": "Previous Workspace Tab" },
|
||||||
|
"command.sidebar.section.1": { "translation": "Sidebar: Section 1" },
|
||||||
|
"command.sidebar.section.2": { "translation": "Sidebar: Section 2" },
|
||||||
|
"command.sidebar.section.3": { "translation": "Sidebar: Section 3" },
|
||||||
|
"command.sidebar.section.4": { "translation": "Sidebar: Section 4" },
|
||||||
|
"command.sidebar.section.5": { "translation": "Sidebar: Section 5" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Diff" },
|
||||||
|
"view.semantics": { "translation": "diff view" },
|
||||||
|
"status.loading": { "translation": "Loading…" },
|
||||||
|
"empty.staged": { "translation": "No staged changes." },
|
||||||
|
"empty.unstaged": { "translation": "No unstaged changes." },
|
||||||
|
"toolbar.unstaged": { "translation": "Unstaged" },
|
||||||
|
"toolbar.unstaged.semantics": { "translation": "show unstaged changes" },
|
||||||
|
"toolbar.staged": { "translation": "Staged" },
|
||||||
|
"toolbar.staged.semantics": { "translation": "show staged changes" },
|
||||||
|
"meta.newFile": { "translation": "new file" },
|
||||||
|
"meta.deleted": { "translation": "deleted" },
|
||||||
|
"meta.renamedFrom": { "translation": "renamed from {path}" },
|
||||||
|
"meta.binary": { "translation": "binary" }
|
||||||
|
}
|
||||||
+3
-1
@@ -1,5 +1,7 @@
|
|||||||
{
|
{
|
||||||
"tab.title": { "translation": "Editor" },
|
"tab.title": { "translation": "Editor" },
|
||||||
|
"chrome.title": { "translation": "editor" },
|
||||||
"empty": { "translation": "Open a file to begin editing." },
|
"empty": { "translation": "Open a file to begin editing." },
|
||||||
"subtitle.no-buffer": { "translation": "no buffer · use `clide open <path>` or pick a file in the tree" }
|
"subtitle.no-buffer": { "translation": "no buffer · use `clide open <path>` or pick a file in the tree" },
|
||||||
|
"a11y.text-area": { "translation": "editor text area" }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"notice.title": { "translation": "Extension management is coming" },
|
||||||
|
"notice.body": { "translation": "Installing, enabling, and disabling extensions arrives with third-party (Lua) extension support. For now the built-in extensions are always on." },
|
||||||
|
"notice.tracked": { "translation": "Tracked in T-8 (Tier 6) · D-16" },
|
||||||
|
"settings.extensions.title": { "translation": "Extensions" },
|
||||||
|
"settings.extensions.section.notice": { "translation": "" },
|
||||||
|
"settings.extensions.field.notice.label": { "translation": "" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Files" },
|
||||||
|
"loading": { "translation": "Loading…" },
|
||||||
|
"empty": { "translation": "No visible files" },
|
||||||
|
"filter.hint": { "translation": "Filter files…" },
|
||||||
|
"a11y.tree": { "translation": "file tree — {name}" },
|
||||||
|
"a11y.collapse": { "translation": "Collapse {name}" },
|
||||||
|
"a11y.expand": { "translation": "Expand {name}" },
|
||||||
|
"a11y.open": { "translation": "Open {name}" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Git" },
|
||||||
|
"panel.semantics": { "translation": "git panel" },
|
||||||
|
"filter.hint": { "translation": "Filter changes…" },
|
||||||
|
"status.loading": { "translation": "Loading…" },
|
||||||
|
"status.clean": { "translation": "Nothing to commit, working tree clean." },
|
||||||
|
"group.conflicts": { "translation": "Merge conflicts" },
|
||||||
|
"group.staged": { "translation": "Staged" },
|
||||||
|
"group.changes": { "translation": "Changes" },
|
||||||
|
"group.untracked": { "translation": "Untracked" },
|
||||||
|
"action.unstageAll": { "translation": "Unstage all" },
|
||||||
|
"action.stageAll": { "translation": "Stage all" },
|
||||||
|
"commit.message.semantics": { "translation": "commit message" },
|
||||||
|
"commit.button": { "translation": "Commit" },
|
||||||
|
"commit.button.semantics": { "translation": "commit staged changes" },
|
||||||
|
"branch.detached": { "translation": "(detached)" },
|
||||||
|
"action.pull": { "translation": "Pull" },
|
||||||
|
"action.pull.semantics": { "translation": "git pull" },
|
||||||
|
"action.push": { "translation": "Push" },
|
||||||
|
"action.push.semantics": { "translation": "git push" },
|
||||||
|
"state.added": { "translation": "added" },
|
||||||
|
"state.modified": { "translation": "modified" },
|
||||||
|
"state.deleted": { "translation": "deleted" },
|
||||||
|
"state.renamed": { "translation": "renamed" },
|
||||||
|
"state.copied": { "translation": "copied" },
|
||||||
|
"state.untracked": { "translation": "untracked" },
|
||||||
|
"row.stage.semantics": { "translation": "stage {name}" },
|
||||||
|
"row.unstage.semantics": { "translation": "unstage {name}" },
|
||||||
|
"row.discard.semantics": { "translation": "discard changes to {name}" },
|
||||||
|
"discard.title": { "translation": "Discard changes?" },
|
||||||
|
"discard.body": { "translation": "Unstaged changes to {name} will be permanently lost." },
|
||||||
|
"button.cancel": { "translation": "Cancel" },
|
||||||
|
"button.discard": { "translation": "Discard" },
|
||||||
|
"branch.switch.semantics": { "translation": "switch branch — {branch}" },
|
||||||
|
"branchPicker.title": { "translation": "Switch branch" },
|
||||||
|
"branchPicker.empty": { "translation": "No branches found." },
|
||||||
|
"branchPicker.loadFailed": { "translation": "failed to load branches" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"tab.graph.title": { "translation": "Graph" },
|
||||||
|
"graph.empty": { "translation": "No linked notes in this vault." },
|
||||||
|
"graph.empty.filtered": { "translation": "No notes match the filter." },
|
||||||
|
"graph.empty.nolocal": { "translation": "Open a note to see its local graph." },
|
||||||
|
"graph.filter.glob": { "translation": "Path glob, e.g. notes/**" },
|
||||||
|
"graph.filter.depth": { "translation": "Local" },
|
||||||
|
"graph.filter.all": { "translation": "All" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"command.preset.default": { "translation": "Keymap: Default" },
|
||||||
|
"command.preset.vim": { "translation": "Keymap: Vim" },
|
||||||
|
"command.preset.vscode": { "translation": "Keymap: VS Code" },
|
||||||
|
"command.preset.jetbrains": { "translation": "Keymap: JetBrains" },
|
||||||
|
"settings.keymap.title": { "translation": "Keymap" },
|
||||||
|
"settings.keymap.section.preset": { "translation": "Preset" },
|
||||||
|
"settings.keymap.field.preset.label": { "translation": "Active preset" },
|
||||||
|
"settings.keymap.field.preset.help": { "translation": "Keyboard layout for the whole app." },
|
||||||
|
"settings.keymap.field.preset.option.default": { "translation": "Default" },
|
||||||
|
"settings.keymap.field.preset.option.vim": { "translation": "Vim" },
|
||||||
|
"settings.keymap.field.preset.option.vscode": { "translation": "VS Code" },
|
||||||
|
"settings.keymap.field.preset.option.jetbrains": { "translation": "JetBrains" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"empty": { "translation": "Select a .md file to preview it here." },
|
||||||
|
"chrome.title": { "translation": "viewer" },
|
||||||
|
"subtitle.lines": { "translation": "{count} lines" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"menu.file": { "translation": "File" },
|
||||||
|
"menu.view": { "translation": "View" },
|
||||||
|
"menu.help": { "translation": "Help" },
|
||||||
|
"about.version": { "translation": "Version" },
|
||||||
|
"about.commit": { "translation": "Commit" },
|
||||||
|
"about.built": { "translation": "Built" },
|
||||||
|
"about.repository": { "translation": "Repository" },
|
||||||
|
"about.checkUpdates": { "translation": "Check for updates" },
|
||||||
|
"about.checking": { "translation": "Checking…" },
|
||||||
|
"about.upToDate": { "translation": "You're on the latest version." },
|
||||||
|
"about.updateAvailable": { "translation": "clide {version} is available — release notes" },
|
||||||
|
"about.updateFailed": { "translation": "Couldn't check for updates" },
|
||||||
|
"licenses.heading": { "translation": "Bundled dependencies" },
|
||||||
|
"licenses.unavailable": { "translation": "Licenses unavailable." },
|
||||||
|
"licenses.loading": { "translation": "Loading…" },
|
||||||
|
"button.close": { "translation": "Close" },
|
||||||
|
"button.cancel": { "translation": "Cancel" },
|
||||||
|
"button.open": { "translation": "Open" },
|
||||||
|
"button.opening": { "translation": "Opening…" },
|
||||||
|
"button.ok": { "translation": "OK" },
|
||||||
|
"dialog.openProject.title": { "translation": "Open project" },
|
||||||
|
"dialog.openProject.body": { "translation": "Enter the path to a git repository." },
|
||||||
|
"dialog.openProject.error": { "translation": "Not a git repository" },
|
||||||
|
"dialog.notRepo.title": { "translation": "No git repo found" },
|
||||||
|
"dialog.notRepo.body": { "translation": "A clide project root requires a git repository." },
|
||||||
|
"command.file.openFolder": { "translation": "File: Open Folder…" },
|
||||||
|
"command.file.newWindow": { "translation": "File: New Window" },
|
||||||
|
"command.file.closeWorkspace": { "translation": "File: Close Project" },
|
||||||
|
"command.help.about": { "translation": "Help: About clide" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"a11y.log": { "translation": "output log" },
|
||||||
|
"empty": { "translation": "No output yet." },
|
||||||
|
"empty.filtered": { "translation": "No output matches the filter." },
|
||||||
|
"filter.hint": { "translation": "Filter…" },
|
||||||
|
"chip.level": { "translation": "Level: {level}" },
|
||||||
|
"chip.source": { "translation": "Source: {source}" },
|
||||||
|
"chip.clear": { "translation": "Clear" },
|
||||||
|
"source.all": { "translation": "all" },
|
||||||
|
"a11y.jumpToLatest": { "translation": "jump to latest" },
|
||||||
|
"jump.label": { "translation": "Jump to latest ↓" },
|
||||||
|
"a11y.toggleDock": { "translation": "toggle output dock" },
|
||||||
|
"dock.label": { "translation": "Output" },
|
||||||
|
"command.dock.toggle": { "translation": "Toggle output dock" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "pql" },
|
||||||
|
"tab.links.title": { "translation": "Links" },
|
||||||
|
"filter.markdown.hint": { "translation": "Filter markdown…" },
|
||||||
|
"loading": { "translation": "Loading…" },
|
||||||
|
"empty.markdown": { "translation": "No markdown files found." },
|
||||||
|
"search.vault.hint": { "translation": "Search vault…" },
|
||||||
|
"search.query.hint": { "translation": "PQL query…" },
|
||||||
|
"backlinks.empty": { "translation": "Open a file to see its links." },
|
||||||
|
"backlinks.loading": { "translation": "Loading…" },
|
||||||
|
"backlinks.semantics": { "translation": "backlinks for {path}" },
|
||||||
|
"group.backlinks": { "translation": "Backlinks" },
|
||||||
|
"group.outlinks": { "translation": "Outlinks" },
|
||||||
|
"group.label": { "translation": "{label} ({count})" },
|
||||||
|
"group.none": { "translation": "None" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Problems" },
|
||||||
|
"semantics.panel": { "translation": "problems panel" },
|
||||||
|
"filter.hint": { "translation": "Filter problems…" },
|
||||||
|
"count": { "translation": "Problems ({count})" },
|
||||||
|
"refresh.label": { "translation": "Refresh" },
|
||||||
|
"refresh.semantics": { "translation": "refresh problems" },
|
||||||
|
"scanning": { "translation": "Scanning…" },
|
||||||
|
"empty": { "translation": "No problems found." }
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"mode.find": { "translation": "Find" },
|
||||||
|
"mode.vault": { "translation": "Vault" },
|
||||||
|
"mode.query": { "translation": "Query" },
|
||||||
|
"mode.markdown": { "translation": "Markdown" },
|
||||||
|
"find.hint": { "translation": "Search" },
|
||||||
|
"replace.hint": { "translation": "Replace" },
|
||||||
|
"include.hint": { "translation": "files to include (e.g. *.dart)" },
|
||||||
|
"exclude.hint": { "translation": "files to exclude" },
|
||||||
|
"toggle.regex": { "translation": "Regular expression" },
|
||||||
|
"toggle.caseInsensitive": { "translation": "Case insensitive" },
|
||||||
|
"status.searching": { "translation": "Searching…" },
|
||||||
|
"status.noResults": { "translation": "No results" },
|
||||||
|
"status.counts": { "translation": "{matches} in {files}" },
|
||||||
|
"a11y.openMatch": { "translation": "Open {path} line {line}" },
|
||||||
|
"button.replaceAll": { "translation": "Replace all" },
|
||||||
|
"button.ok": { "translation": "OK" },
|
||||||
|
"button.cancel": { "translation": "Cancel" },
|
||||||
|
"button.confirm": { "translation": "Confirm" },
|
||||||
|
"dialog.dirty.title": { "translation": "Working tree not clean" },
|
||||||
|
"dialog.dirty.body": { "translation": "Commit or stash your changes before replacing — git is the only undo." },
|
||||||
|
"dialog.confirm.body": { "translation": "Replace {matches} match(es) across {files} file(s)? This cannot be undone in clide." }
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"command.open": { "translation": "Settings…" },
|
||||||
|
"modal.title": { "translation": "Settings" },
|
||||||
|
"modal.close": { "translation": "Close" },
|
||||||
|
"modal.close.hint": { "translation": "Close settings without changing anything" },
|
||||||
|
"rail.header": { "translation": "Categories" },
|
||||||
|
"panel.empty": { "translation": "No settings categories are registered yet." },
|
||||||
|
"search.hint": { "translation": "Search settings…" },
|
||||||
|
"search.empty": { "translation": "No settings match your search." },
|
||||||
|
"scope.project": { "translation": "This project" },
|
||||||
|
"scope.always": { "translation": "All clide" },
|
||||||
|
"scope.default": { "translation": "Default" },
|
||||||
|
"scope.reset": { "translation": "Reset to default" },
|
||||||
|
"scope.tip.project": { "translation": "Stored in this project (.clide)" },
|
||||||
|
"scope.tip.always": { "translation": "Stored for all clide (~/.clide)" },
|
||||||
|
"scope.tip.default": { "translation": "Unset — using the default" }
|
||||||
|
}
|
||||||
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"tab.title": { "translation": "Terminal" },
|
"tab.title": { "translation": "Terminal" },
|
||||||
|
"chrome.title": { "translation": "terminal" },
|
||||||
"subtitle.spawning": { "translation": "spawning shell…" },
|
"subtitle.spawning": { "translation": "spawning shell…" },
|
||||||
"subtitle.exited": { "translation": "Shell exited." },
|
"subtitle.exited": { "translation": "Shell exited." },
|
||||||
"error.unavailable": { "translation": "Terminal unavailable" },
|
"error.unavailable": { "translation": "Terminal unavailable" },
|
||||||
"error.daemon": { "translation": "Backend not connected." }
|
"error.daemon": { "translation": "Backend not connected." },
|
||||||
|
"a11y.label": { "translation": "terminal — {subtitle}" }
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"command.pick": { "translation": "Theme…" },
|
||||||
|
"modal.title": { "translation": "Select theme" },
|
||||||
|
"modal.cancel": { "translation": "Cancel" },
|
||||||
|
"modal.cancel.hint": { "translation": "Close the theme picker without changing the current theme" },
|
||||||
|
"row.select.hint": { "translation": "Activate this theme" },
|
||||||
|
"section.appearance": { "translation": "Appearance" },
|
||||||
|
"toggle.highContrast": { "translation": "High contrast" },
|
||||||
|
"settings.appearance.title": { "translation": "Appearance" },
|
||||||
|
"settings.appearance.section.theme": { "translation": "Theme" },
|
||||||
|
"settings.appearance.section.typography": { "translation": "Typography" },
|
||||||
|
"settings.appearance.field.theme.label": { "translation": "Theme" },
|
||||||
|
"settings.appearance.field.theme.help": { "translation": "Color theme; high contrast switches to the accessible variant." },
|
||||||
|
"settings.appearance.field.uiFont.label": { "translation": "UI font" },
|
||||||
|
"settings.appearance.field.uiFont.help": { "translation": "Typeface for the app interface; applies live." },
|
||||||
|
"settings.appearance.field.uiFont.option.josefinSans": { "translation": "Josefin Sans" },
|
||||||
|
"settings.appearance.field.uiFont.option.inter": { "translation": "Inter" },
|
||||||
|
"settings.appearance.field.monoFont.label": { "translation": "Monospace font" },
|
||||||
|
"settings.appearance.field.monoFont.help": { "translation": "Terminal, diffs, code, and IDs; applies live." },
|
||||||
|
"settings.appearance.field.monoFont.option.jetBrainsMono": { "translation": "JetBrains Mono" },
|
||||||
|
"settings.appearance.field.monoFont.option.firaMono": { "translation": "Fira Mono" },
|
||||||
|
"settings.appearance.section.language": { "translation": "Language" },
|
||||||
|
"settings.appearance.field.language.label": { "translation": "Language" },
|
||||||
|
"settings.appearance.field.language.help": { "translation": "Language for the app interface; applies live." }
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"tab.title": { "translation": "Tickets" },
|
||||||
|
"tab.detail.title": { "translation": "Ticket" },
|
||||||
|
"type.initiative": { "translation": "Initiative" },
|
||||||
|
"type.epic": { "translation": "Epic" },
|
||||||
|
"type.story": { "translation": "Story" },
|
||||||
|
"type.task": { "translation": "Task" },
|
||||||
|
"type.bug": { "translation": "Bug" },
|
||||||
|
"loading": { "translation": "Loading tickets..." },
|
||||||
|
"error.load": { "translation": "failed to load tickets" },
|
||||||
|
"empty": { "translation": "No tickets.\nRun `pql ticket new` to create one." },
|
||||||
|
"filter.hint": { "translation": "Filter tickets…" },
|
||||||
|
"refresh.tooltip": { "translation": "Refresh tickets" },
|
||||||
|
"section.in_progress": { "translation": "IN PROGRESS" },
|
||||||
|
"section.review": { "translation": "REVIEW" },
|
||||||
|
"section.ready": { "translation": "READY" },
|
||||||
|
"section.backlog": { "translation": "BACKLOG" },
|
||||||
|
"section.done": { "translation": "DONE" },
|
||||||
|
"section.cancelled": { "translation": "CANCELLED" },
|
||||||
|
"chip.label": { "translation": "{type} type filter" },
|
||||||
|
"chip.tooltip": { "translation": "Click to toggle · double-click to isolate" },
|
||||||
|
"badge.wip": { "translation": "WIP" },
|
||||||
|
"badge.review": { "translation": "REVIEW" },
|
||||||
|
"badge.cancelled": { "translation": "CANCELLED" },
|
||||||
|
"pickUp.tooltip": { "translation": "Pick up — hand this ticket to the Claude pane" },
|
||||||
|
"detail.loading": { "translation": "Loading…" },
|
||||||
|
"detail.empty": { "translation": "Select a ticket to view details." },
|
||||||
|
"detail.assigned": { "translation": "assigned: {name}" },
|
||||||
|
"detail.section.parents": { "translation": "PARENT TREE" },
|
||||||
|
"detail.section.decisions": { "translation": "REFERENCED DECISIONS" },
|
||||||
|
"status.backlog": { "translation": "BACKLOG" },
|
||||||
|
"status.ready": { "translation": "READY" },
|
||||||
|
"status.in_progress": { "translation": "WIP" },
|
||||||
|
"status.review": { "translation": "REVIEW" },
|
||||||
|
"status.done": { "translation": "DONE" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"command.detect": { "translation": "Re-detect tool paths" },
|
||||||
|
"settings.title": { "translation": "Tools" },
|
||||||
|
"settings.section.binaries": { "translation": "Supporter binaries" },
|
||||||
|
"settings.field.claude.label": { "translation": "Claude CLI" },
|
||||||
|
"settings.field.claude.help": { "translation": "Absolute path to the claude binary; blank to auto-resolve." },
|
||||||
|
"settings.field.d2.label": { "translation": "d2" },
|
||||||
|
"settings.field.d2.help": { "translation": "Absolute path to the d2 diagram compiler; blank to auto-resolve." },
|
||||||
|
"settings.field.detect.label": { "translation": "Re-detect" },
|
||||||
|
"settings.field.detect.help": { "translation": "Re-scan PATH and the common install dirs, overwriting the paths above." },
|
||||||
|
"settings.section.path": { "translation": "Workspace PATH" },
|
||||||
|
"settings.field.pathPreset.label": { "translation": "Prepend to PATH" },
|
||||||
|
"settings.field.pathPreset.help": { "translation": "Directories put ahead of PATH in Claude sessions and terminal panes spawned for this repo; worktrees share the repo's preset. Applies to new shells." },
|
||||||
|
"path.noWorkspace": { "translation": "Open a workspace to set its PATH preset." },
|
||||||
|
"path.sharedRoot": { "translation": "Worktree — preset shared with" },
|
||||||
|
"path.empty": { "translation": "No preset entries — spawned shells get the resolved login-shell PATH as-is." },
|
||||||
|
"path.add": { "translation": "Add entry" },
|
||||||
|
"path.invalid": { "translation": "Enter an absolute path (or ~/…)." },
|
||||||
|
"path.missing": { "translation": "missing" },
|
||||||
|
"path.moveUp": { "translation": "Move up" },
|
||||||
|
"path.moveDown": { "translation": "Move down" },
|
||||||
|
"path.remove": { "translation": "Remove" },
|
||||||
|
"path.capture": { "translation": "Suggest from login shell" },
|
||||||
|
"path.captureNone": { "translation": "Nothing to suggest — the login-shell PATH is already covered." },
|
||||||
|
"path.addSuggestion": { "translation": "Add suggested entry" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"command.view.zoomIn": { "translation": "View: Zoom In" },
|
||||||
|
"command.view.zoomOut": { "translation": "View: Zoom Out" },
|
||||||
|
"command.view.zoomReset": { "translation": "View: Reset Zoom" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mode.normal": { "translation": "NORMAL" },
|
||||||
|
"mode.insert": { "translation": "INSERT" },
|
||||||
|
"mode.visual": { "translation": "VISUAL" },
|
||||||
|
"command.vim.mode.normal": { "translation": "Vim: Normal mode" },
|
||||||
|
"command.vim.mode.insert": { "translation": "Vim: Insert mode" },
|
||||||
|
"command.vim.mode.visual": { "translation": "Vim: Visual mode" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"title": { "translation": "clide" },
|
||||||
|
"subtitle": { "translation": "IDE for Claude Code CLI" },
|
||||||
|
"open-project": { "translation": "Open project" },
|
||||||
|
"open-project.hint": { "translation": "Pick a git repository to open as the workspace" },
|
||||||
|
"tab.title": { "translation": "Welcome" },
|
||||||
|
"section.tips": { "translation": "TIPS" },
|
||||||
|
"section.start": { "translation": "START" },
|
||||||
|
"section.recent": { "translation": "RECENT" },
|
||||||
|
"tips.quickOpen": { "translation": "Quick open" },
|
||||||
|
"tips.commandPalette": { "translation": "Command palette" },
|
||||||
|
"tips.toggleSidebar": { "translation": "Toggle sidebar" },
|
||||||
|
"tips.toggleContext": { "translation": "Toggle context" },
|
||||||
|
"tips.findInFiles": { "translation": "Find in files" },
|
||||||
|
"tips.focusMode": { "translation": "Focus mode" },
|
||||||
|
"action.openFolder": { "translation": "Open folder…" },
|
||||||
|
"action.newProject": { "translation": "New project…" },
|
||||||
|
"dialog.newProject.title": { "translation": "New project" },
|
||||||
|
"dialog.newProject.body": { "translation": "Creates a git repo + a CLAUDE.md, then opens it." },
|
||||||
|
"button.create": { "translation": "Create" },
|
||||||
|
"button.creating": { "translation": "Creating…" },
|
||||||
|
"recent.empty": { "translation": "No recent projects." },
|
||||||
|
"sticky.label": { "translation": "always open this project on launch" },
|
||||||
|
"sticky.tooltip": { "translation": "Always open this project on launch" },
|
||||||
|
"sticky.tooltip.active": { "translation": "Always open this project on launch (uncheck to restore picker)" },
|
||||||
|
"status.checking": { "translation": "checking…" },
|
||||||
|
"status.ok": { "translation": "application ok" },
|
||||||
|
"status.notFound": { "translation": "{tool} not found" },
|
||||||
|
"status.theme": { "translation": "theme: " },
|
||||||
|
"dialog.openProject.title": { "translation": "Open project" },
|
||||||
|
"dialog.openProject.body": { "translation": "Enter the path to a git repository." },
|
||||||
|
"dialog.openProject.error": { "translation": "Not a git repository" },
|
||||||
|
"button.cancel": { "translation": "Cancel" },
|
||||||
|
"button.open": { "translation": "Open" },
|
||||||
|
"button.opening": { "translation": "Opening…" },
|
||||||
|
"button.ok": { "translation": "OK" },
|
||||||
|
"dialog.notRepo.title": { "translation": "No git repo found" },
|
||||||
|
"dialog.notRepo.body": { "translation": "A clide project needs a git repository. Initialize this folder as one?" },
|
||||||
|
"dialog.notRepo.initialize": { "translation": "Initialize project" },
|
||||||
|
"button.initializing": { "translation": "Initializing…" },
|
||||||
|
"command.workspace.open-project": { "translation": "Workspace: Open project…" }
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"collapser.expand": { "translation": "Expand" },
|
||||||
|
"collapser.collapse": { "translation": "Collapse" },
|
||||||
|
"collapser.expanded": { "translation": "expanded" },
|
||||||
|
"collapser.collapsed": { "translation": "collapsed" },
|
||||||
|
"toast.dismiss": { "translation": "Dismiss notification" },
|
||||||
|
"lightbox.close": { "translation": "close" },
|
||||||
|
"lightbox.hint": { "translation": "scroll to zoom · double-click to reset · Esc to close" },
|
||||||
|
"tab.new": { "translation": "New tab" },
|
||||||
|
"exline.notCommand": { "translation": "Not an editor command" },
|
||||||
|
"spine.expandSuffix": { "translation": "click to expand" },
|
||||||
|
"pane.close": { "translation": "Close pane" },
|
||||||
|
"pane.header": { "translation": "pane header: {title}" },
|
||||||
|
"reader.back": { "translation": "Back" },
|
||||||
|
"reader.forward": { "translation": "Forward" },
|
||||||
|
"reader.jumpToPin": { "translation": "Jump to pin" },
|
||||||
|
"reader.edit": { "translation": "Edit in editor" },
|
||||||
|
"reader.pin": { "translation": "Pin" },
|
||||||
|
"reader.unpin": { "translation": "Unpin" },
|
||||||
|
"link.openInEditor": { "translation": "Open in editor" },
|
||||||
|
"resize.axis.width": { "translation": "width" },
|
||||||
|
"resize.axis.height": { "translation": "height" },
|
||||||
|
"resize.sidebar": { "translation": "Sidebar {axis}" },
|
||||||
|
"resize.contextPanel": { "translation": "Context panel {axis}" },
|
||||||
|
"resize.slot": { "translation": "{slot} {axis}" },
|
||||||
|
"resize.pixels": { "translation": "{n} pixels" }
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user