agent-bios 0.9.9 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -48,51 +48,19 @@
48
48
  {"anchor": "Treat a produced field, flag, signal", "tier": "domain", "domains": ["llm-pipeline-dev"]},
49
49
  {"anchor": "Hard-block only deterministically decidable structural", "tier": "domain", "domains": ["llm-pipeline-dev"]},
50
50
  {"anchor": "Runtime/code may enforce the contract", "tier": "domain", "domains": ["llm-pipeline-dev"]},
51
- {"anchor": "Keep the concept graph compact by reusing", "tier": "domain", "domains": ["builder-base"]},
52
- {"anchor": "Treat lasting or shared names as concept", "tier": "domain", "domains": ["builder-base"]},
53
- {"anchor": "Before adding or changing a concept", "tier": "domain", "domains": ["builder-base"]},
54
- {"anchor": "Prefer broad, stable concepts with precise", "tier": "domain", "domains": ["builder-base"]},
51
+ {"anchor": "When adding, changing, renaming, splitting, or exposing anything lasting or shared", "tier": "domain", "domains": ["builder-base"]},
55
52
  {"anchor": "Before fixing a review finding or test failure", "tier": "domain", "domains": ["builder-base"]},
56
- {"anchor": "Split or promote a concept when it changes", "tier": "domain", "domains": ["builder-base"]},
57
- {"anchor": "Keep derived values as properties or projections", "tier": "domain", "domains": ["builder-base"]},
58
- {"anchor": "Keep internal projections and helper outputs internal", "tier": "domain", "domains": ["builder-base"]},
59
- {"anchor": "Distinguish authority from visibility", "tier": "domain", "domains": ["builder-base"]},
60
- {"anchor": "Reuse existing enum values, failure kinds", "tier": "domain", "domains": ["builder-base"]},
61
- {"anchor": "Use fallback paths, compatibility shims", "tier": "domain", "domains": ["builder-base"]},
62
- {"anchor": "Keep comments and active docs aligned", "tier": "domain", "domains": ["builder-base"]},
63
- {"anchor": "When a split is necessary, name the parent", "tier": "domain", "domains": ["builder-base"]},
64
- {"anchor": "In ontology work, check existing entities", "tier": "domain", "domains": ["builder-base"]},
65
- {"anchor": "In code work, follow existing naming patterns", "tier": "domain", "domains": ["builder-base"]},
66
- {"anchor": "Let the repository's shape mirror its concept graph", "tier": "domain", "domains": ["builder-base"]},
67
53
  {"anchor": "For `.xlsx` editing, generation, reconciliation", "tier": "domain", "domains": ["office-work"]},
68
- {"anchor": "For meaningful development work, read and use", "tier": "domain", "domains": ["builder-base"]},
54
+ {"anchor": "For development work, read and use", "tier": "domain", "domains": ["builder-base"]},
69
55
  {"anchor": "For mock, fixture, fake, stub, simulated-provider", "tier": "domain", "domains": ["builder-base"]},
70
- {"anchor": "When the user asks to", "tier": "domain", "domains": ["builder-base"]},
71
- {"anchor": "Think before coding: state key assumptions", "tier": "domain", "domains": ["builder-base"]},
72
- {"anchor": "Build the smallest viable functional path", "tier": "domain", "domains": ["builder-base"]},
73
- {"anchor": "Treat viability as real behavior against", "tier": "domain", "domains": ["builder-base"]},
74
- {"anchor": "Make surgical changes. Touch only what", "tier": "domain", "domains": ["builder-base"]},
75
- {"anchor": "Clean up issues introduced by the current", "tier": "domain", "domains": ["builder-base"]},
76
56
  {"anchor": "Own the full lifecycle of what you create", "tier": "domain", "domains": ["builder-base"]},
77
- {"anchor": "Define success criteria before multi-step coding work", "tier": "domain", "domains": ["builder-base"]},
78
- {"anchor": "For bugs, prefer a reproducing test", "tier": "domain", "domains": ["builder-base"]},
79
- {"anchor": "Every changed line should trace back", "tier": "domain", "domains": ["builder-base"]},
80
- {"anchor": "Fix the root cause at its authority", "tier": "domain", "domains": ["builder-base"]},
81
57
  {"anchor": "Land risky or behavior-changing work behind", "tier": "domain", "domains": ["builder-base"]},
82
58
  {"anchor": "For composing a review request, packet", "tier": "domain", "domains": ["builder-base"]},
83
59
  {"anchor": "After every meaningful code, ontology, config", "tier": "domain", "domains": ["builder-base"]},
84
- {"anchor": "Use static checks broadly: typecheck, lint", "tier": "domain", "domains": ["builder-base"]},
85
- {"anchor": "Add the narrowest reliable runtime or semantic test", "tier": "domain", "domains": ["builder-base"]},
86
- {"anchor": "Pick each domain's verification mix", "tier": "domain", "domains": ["builder-base"]},
87
- {"anchor": "Let the LLM derive scenarios from the diff", "tier": "domain", "domains": ["builder-base"]},
88
- {"anchor": "Keep E2E stable with deterministic data", "tier": "domain", "domains": ["builder-base"]},
60
+ {"anchor": "For choosing verification depth, the per-domain mix, the case space, what makes a completion criterion falsifiable", "tier": "domain", "domains": ["builder-base"]},
89
61
  {"anchor": "Report the checks run, results", "tier": "core", "domains": []},
90
62
  {"anchor": "Trust a green check only when it traversed", "tier": "domain", "domains": ["builder-base"]},
91
- {"anchor": "Make completion criteria falsifiable", "tier": "domain", "domains": ["builder-base"]},
92
63
  {"anchor": "Before comparing two of anything", "tier": "domain", "domains": ["builder-base"]},
93
- {"anchor": "For non-trivial designs or high-risk changes", "tier": "domain", "domains": ["builder-base"]},
94
- {"anchor": "Proportion verification to cost, risk, and information gain", "tier": "domain", "domains": ["builder-base"]},
95
- {"anchor": "Trust a green / zero-findings verdict only", "tier": "domain", "domains": ["builder-base"]},
96
64
  {"anchor": "For concrete shell/CLI traps", "tier": "domain", "domains": ["builder-base"]},
97
65
  {"anchor": "Ambient state — the active shell", "tier": "domain", "domains": ["builder-base"]},
98
66
  {"anchor": "Before relying on any model id", "tier": "domain", "domains": ["builder-base"]},
@@ -100,7 +68,6 @@
100
68
  {"anchor": "Never accept secrets through transcript- or history-logged channels", "tier": "core", "domains": []},
101
69
  {"anchor": "When a secret must be supplied", "tier": "domain", "domains": ["builder-base"]},
102
70
  {"anchor": "Treat a coarse runtime signal", "tier": "domain", "domains": ["builder-base"]},
103
- {"anchor": "Before reasoning about what a branch contains", "tier": "domain", "domains": ["builder-base"]},
104
71
  {"anchor": "Standing spawn policy: check the spawn gates", "tier": "domain", "domains": ["multi-agent-orchestration"]},
105
72
  {"anchor": "Down-spawns carry a machine-checkable done-when", "tier": "domain", "domains": ["multi-agent-orchestration"]},
106
73
  {"anchor": "For work spanning multiple models or CLI agents", "tier": "domain", "domains": ["multi-agent-orchestration"]},
@@ -111,11 +78,7 @@
111
78
  {"anchor": "Never retry-storm a live rate limit", "tier": "domain", "domains": ["multi-agent-orchestration"]},
112
79
  {"anchor": "On any resumed, cleared, or relocated session", "tier": "domain", "domains": ["multi-agent-orchestration"]},
113
80
  {"anchor": "Keep runtime code, active docs, and execution-facing", "tier": "domain", "domains": ["builder-base"]},
114
- {"anchor": "Use comments for non-obvious current behavior", "tier": "domain", "domains": ["builder-base"]},
115
- {"anchor": "Put backward-compatibility notes, deprecated behavior", "tier": "domain", "domains": ["builder-base"]},
116
- {"anchor": "Link from active docs or code to isolated notes", "tier": "domain", "domains": ["builder-base"]},
117
- {"anchor": "Phrase guidelines as desired behavior", "tier": "domain", "domains": ["builder-base"]},
118
- {"anchor": "Prefer established docs such as", "tier": "domain", "domains": ["builder-base"]},
81
+ {"anchor": "For where a comment, a compatibility note, deprecated behavior, a rejected alternative", "tier": "domain", "domains": ["builder-base"]},
119
82
  {"anchor": "For SVG diagrams, service blueprints", "tier": "domain", "domains": ["visualization-docs"]},
120
83
  {"anchor": "When a concept is easier to understand visually", "tier": "domain", "domains": ["visualization-docs"]},
121
84
  {"anchor": "Use HTML for comparisons, flows, state changes", "tier": "domain", "domains": ["visualization-docs"]},
@@ -126,10 +89,12 @@
126
89
  {"anchor": "`learn!` — session learning", "tier": "core", "domains": []}
127
90
  ],
128
91
  "guides": {
129
- "claude-prompting.md": {"tier": "domain", "domains": ["multi-agent-orchestration"]},
130
- "cli-multi-model-workflow.md": {"tier": "domain", "domains": ["multi-agent-orchestration"]},
92
+ "claude-prompting.md": {"tier": "domain", "domains": ["multi-agent-orchestration"], "handles": ["per-family prompting guide", "계열별 prompting guide"]},
93
+ "cli-multi-model-workflow.md": {"tier": "domain", "domains": ["multi-agent-orchestration"], "handles": ["multi-model guide", "multi-model 가이드"]},
131
94
  "coding-staged-workflow.md": {"tier": "domain", "domains": ["builder-base"]},
132
- "gpt-prompting.md": {"tier": "domain", "domains": ["multi-agent-orchestration"]},
95
+ "concept-economy.md": {"tier": "domain", "domains": ["builder-base"]},
96
+ "documentation-hygiene.md": {"tier": "domain", "domains": ["builder-base"]},
97
+ "gpt-prompting.md": {"tier": "domain", "domains": ["multi-agent-orchestration"], "handles": ["prompting guides for gpt-family"]},
133
98
  "implementation-map.md": {"tier": "domain", "domains": ["visualization-docs"]},
134
99
  "llm-capability-boundary-examples.md": {"tier": "domain", "domains": ["llm-pipeline-dev"]},
135
100
  "llm-capability-boundary-patterns.md": {"tier": "domain", "domains": ["llm-pipeline-dev"]},
@@ -139,6 +104,7 @@
139
104
  "session-distill-workflow.md": {"tier": "infra", "domains": []},
140
105
  "learning-flow.md": {"tier": "infra", "domains": []},
141
106
  "svg-visualization-guide.md": {"tier": "domain", "domains": ["visualization-docs"]},
107
+ "verification-discipline.md": {"tier": "domain", "domains": ["builder-base"]},
142
108
  "tooling-gotchas.md": {"tier": "domain", "domains": ["builder-base"]}
143
109
  },
144
110
  "hooks": {
package/install.sh CHANGED
@@ -622,11 +622,27 @@ cmd_install() {
622
622
  # package.json (version + releaseDate) — distinct from the corpus content
623
623
  # version. Best-effort: a failure here never fails the install.
624
624
  if [ "$DRY_RUN" != 1 ]; then
625
- if python3 - "$REPO/package.json" "$STATE_DIR/version.json" <<'PY' 2>/dev/null
626
- import json, sys
625
+ if python3 - "$REPO/package.json" "$STATE_DIR/version.json" "$REPO/provenance.json" \
626
+ "$([ -e "$REPO/.git" ] && echo clone || echo package)" <<'PY' 2>/dev/null
627
+ import json, os, sys
627
628
  pkg = json.load(open(sys.argv[1]))
629
+ out = {"version": pkg.get("version"), "releaseDate": pkg.get("releaseDate"),
630
+ "source": sys.argv[4]}
631
+ # Publication provenance rides along ONLY for a package-layout source: in a
632
+ # clone, git itself is the live provenance and a provenance.json on disk is by
633
+ # definition residue (a failed pack's leftover stamp) — ingesting it once let a
634
+ # clone deployment of commit B carry a stale label A into the state marker.
635
+ if sys.argv[4] == "package" and os.path.isfile(sys.argv[3]):
636
+ try:
637
+ prov = json.load(open(sys.argv[3]))
638
+ if prov.get("commit"):
639
+ out["commit"] = prov["commit"]
640
+ if prov.get("dirty"):
641
+ out["dirty"] = True
642
+ except Exception:
643
+ pass
628
644
  with open(sys.argv[2], "w") as f:
629
- json.dump({"version": pkg.get("version"), "releaseDate": pkg.get("releaseDate")}, f)
645
+ json.dump(out, f)
630
646
  f.write("\n")
631
647
  PY
632
648
  then
@@ -656,8 +672,8 @@ verify_present() { if [ -f "$1" ]; then return 0; else log "missing $1"; return
656
672
 
657
673
  cmd_verify() {
658
674
  local fail=0 gp gb
659
- if [ ! -d "$REPO/.git" ] && [ "$(drift_state)" = "drift" ]; then
660
- log "deploy drift: deployed $(deployed_version), package $(source_version) — run: agent-bios install"
675
+ if [ ! -e "$REPO/.git" ] && [ "$(drift_state)" = "drift" ]; then
676
+ log "deploy drift: $(drift_detail) — run: agent-bios install"
661
677
  fail=1
662
678
  fi
663
679
  # Not mode-specific: an author-only guide must be absent from EVERY directory any
@@ -982,30 +998,131 @@ sys.exit(0) if v is None else print(v)' "$1" "$2" 2>/dev/null
982
998
  deployed_version() { json_field "$STATE_DIR/version.json" version; }
983
999
  source_version() { json_field "$REPO/package.json" version; }
984
1000
 
1001
+ json_true() { # exit 0 iff $2 in $1 is JSON true — json.dump writes '"k": true'
1002
+ # with a space, so byte-matching a compact spelling read the real writer's
1003
+ # output as false forever.
1004
+ [ -f "$1" ] || return 1
1005
+ python3 -c 'import json,sys
1006
+ try:
1007
+ v=json.load(open(sys.argv[1])).get(sys.argv[2])
1008
+ except Exception:
1009
+ sys.exit(1)
1010
+ sys.exit(0 if v is True else 1)' "$1" "$2" 2>/dev/null
1011
+ }
1012
+
1013
+ current_commit() { # the CURRENT side's commit: git HEAD in a clone, the stamp in a package
1014
+ # A clone's provenance is its live HEAD — a provenance.json on its disk is a
1015
+ # failed pack's residue, and reading it once let a stale label A match a
1016
+ # checkout sitting at B.
1017
+ if [ -e "$REPO/.git" ]; then
1018
+ git -C "$REPO" rev-parse HEAD 2>/dev/null || true
1019
+ else
1020
+ json_field "$REPO/provenance.json" commit 2>/dev/null || true
1021
+ fi
1022
+ }
1023
+
1024
+ current_dirty() { # exit 0 iff the current side is a dirty-stamped PACKAGE artifact
1025
+ [ ! -e "$REPO/.git" ] && json_true "$REPO/provenance.json" dirty
1026
+ }
1027
+
985
1028
  drift_state() { # prints: match | drift | unknown
986
- local d s
1029
+ local d s dc sc
987
1030
  d="$(deployed_version)" || { echo unknown; return; }
988
1031
  s="$(source_version)" || { echo unknown; return; }
989
1032
  [ -n "$d" ] && [ -n "$s" ] || { echo unknown; return; }
990
- [ "$d" = "$s" ] && echo match || echo drift
1033
+ [ "$d" = "$s" ] || { echo drift; return; }
1034
+ # Same VERSION is not same SOURCE: two locally packed tarballs keep one
1035
+ # version across different commits (npm pack is an accommodated flow), and
1036
+ # the commit was persisted into version.json exactly so this comparison
1037
+ # could read it. Judged only when both sides carry one — a clone deploy
1038
+ # stamps no commit, and half a comparison is none.
1039
+ dc="$(json_field "$STATE_DIR/version.json" commit 2>/dev/null || true)"
1040
+ sc="$(current_commit)"
1041
+ # Dirt is judged BEFORE the commit comparison: a dirty artifact's bytes are
1042
+ # described by no commit, so differing commit labels prove nothing about
1043
+ # differing payloads — unknown, not drift, or npm-layout verify fails on a
1044
+ # mismatch nobody proved.
1045
+ if json_true "$STATE_DIR/version.json" dirty || current_dirty; then
1046
+ echo unknown; return
1047
+ fi
1048
+ if [ -n "$dc" ] && [ -n "$sc" ] && [ "$dc" != "$sc" ]; then
1049
+ echo drift; return
1050
+ fi
1051
+ # UNPROVABLE is not drift: an unbound side (npm layout without a commit — a
1052
+ # lifecycle-disabled pack, or the hook's materialized tree) and a DIRTY side
1053
+ # (bytes no commit describes; parsed via json_true, never byte-matched,
1054
+ # because json.dump's spacing defeated the compact grep) both make the
1055
+ # correspondence unprovable. Drift is a PROVEN mismatch and makes verify
1056
+ # fail; branding the unprovable as drift made D-0050's accepted install path
1057
+ # fail its own verification. Clone deployments stay version-compared — git
1058
+ # itself is their live provenance, and they persist no commit by design.
1059
+ if [ "$(json_field "$STATE_DIR/version.json" source 2>/dev/null || true)" = "package" ] \
1060
+ && [ -z "$dc" ]; then
1061
+ echo unknown; return
1062
+ fi
1063
+ if [ ! -e "$REPO/.git" ] && [ -z "$sc" ]; then
1064
+ echo unknown; return
1065
+ fi
1066
+ echo match
1067
+ }
1068
+
1069
+ drift_detail() { # one line naming WHAT drifted: versions, or commits behind one version
1070
+ local d s dc sc
1071
+ d="$(deployed_version)"; s="$(source_version)"
1072
+ dc="$(json_field "$STATE_DIR/version.json" commit 2>/dev/null || true)"
1073
+ sc="$(current_commit)"
1074
+ if [ "$d" = "$s" ] && { json_true "$STATE_DIR/version.json" dirty || current_dirty; }; then
1075
+ printf 'a DIRTY-packed artifact is involved — its bytes are described by no commit; a clean-pack redeploy restores a provable match'
1076
+ elif [ "$d" = "$s" ] && [ -n "$dc" ] && [ -n "$sc" ] && [ "$dc" != "$sc" ]; then
1077
+ printf 'deployed commit %s but this source is at %s (both version %s)' "$dc" "$sc" "$s"
1078
+ elif [ "$(json_field "$STATE_DIR/version.json" source 2>/dev/null || true)" = "package" ] \
1079
+ && [ -z "$dc" ]; then
1080
+ printf 'the deployed artifact is UNBOUND (packed with lifecycle scripts disabled) — its bytes are proven by no commit; a bound redeploy restores a provable match'
1081
+ elif [ ! -e "$REPO/.git" ] && [ -z "$sc" ]; then
1082
+ printf 'this package is UNBOUND (no provenance) — its bytes are proven by no commit'
1083
+ else
1084
+ printf 'deployed %s but this package is %s' "$d" "$s"
1085
+ fi
991
1086
  }
992
1087
 
993
1088
  cmd_status() {
994
1089
  local version p
995
- if [ -d "$REPO/.git" ]; then
1090
+ if [ -e "$REPO/.git" ]; then
996
1091
  version="$(git -C "$REPO" describe --tags --always --dirty 2>/dev/null || git -C "$REPO" rev-parse --short HEAD 2>/dev/null || echo '?')"
997
1092
  log "agent-bios (git clone: $version)"
998
1093
  elif [ -f "$REPO/package.json" ]; then
999
1094
  version="$(node -e "try{process.stdout.write(require('$REPO/package.json').version)}catch(e){process.stdout.write('?')}" 2>/dev/null || echo '?')"
1000
1095
  log "agent-bios (npm package: $version)"
1096
+ if [ -f "$REPO/provenance.json" ]; then
1097
+ local built_from
1098
+ # Tolerated, never trusted: a malformed stamp used to kill status via
1099
+ # set -e mid-output, and a well-formed one with no commit passed in
1100
+ # silence — both are UNBOUND states, not absences of the question.
1101
+ built_from="$(json_field "$REPO/provenance.json" commit 2>/dev/null || true)"
1102
+ if [ -n "$built_from" ]; then
1103
+ info "built from commit ${built_from}$(
1104
+ grep -q '"dirty":true' "$REPO/provenance.json" && printf ' (DIRTY tree at pack time)')"
1105
+ else
1106
+ info "UNBOUND provenance.json is unreadable or names no commit — this artifact is not usably bound"
1107
+ fi
1108
+ else
1109
+ # The absence is the finding: D-0050 accepts lifecycle-disabled packs as
1110
+ # residual BECAUSE this line makes an unbound artifact visible — a silent
1111
+ # skip here would unmake that decision's premise.
1112
+ info "UNBOUND no provenance stamp — packed with lifecycle scripts disabled, or a pre-provenance release; this artifact names no commit"
1113
+ fi
1001
1114
  else
1002
1115
  log "agent-bios"
1003
1116
  fi
1004
1117
  log " source: $REPO"
1005
1118
  case "$(drift_state)" in
1006
1119
  match) info "deployed version $(deployed_version) (matches this package)" ;;
1007
- drift) log "DRIFT deployed $(deployed_version) but this package is $(source_version) — run: agent-bios install" ;;
1008
- unknown) info "deployed version unknown (no state marker yet)" ;;
1120
+ drift) log "DRIFT $(drift_detail) — run: agent-bios install" ;;
1121
+ unknown) if [ -f "$STATE_DIR/version.json" ]; then
1122
+ info "correspondence unprovable: $(drift_detail)"
1123
+ else
1124
+ info "deployed version unknown (no state marker yet)"
1125
+ fi ;;
1009
1126
  esac
1010
1127
  for p in "$CLAUDE_DIR/CLAUDE.md" "$CODEX_DIR/AGENTS.md" "$BIN_DIR/agent-launch" \
1011
1128
  "$LAUNCH_DIR/profiles.toml" "$LAUNCH_DIR/shell.zsh"; do
@@ -1015,7 +1132,7 @@ cmd_status() {
1015
1132
  }
1016
1133
 
1017
1134
  cmd_update() {
1018
- if [ -d "$REPO/.git" ]; then
1135
+ if [ -e "$REPO/.git" ]; then
1019
1136
  log "Updating from git..."
1020
1137
  run git -C "$REPO" pull --ff-only
1021
1138
  cmd_install
@@ -1067,7 +1184,7 @@ EOF
1067
1184
  # than naming none: a clone can roll the corpus back to a registered mining window, while an
1068
1185
  # npm install has no git history to read and rolls the whole package back by version instead.
1069
1186
  # Derived from which install this is, for the same reason --with names is.
1070
- if [ -d "$REPO/.git" ]; then
1187
+ if [ -e "$REPO/.git" ]; then
1071
1188
  printf '\nRecover: python3 %s/compose/corpus-state.py list, then rollback --version V\n' "$REPO"
1072
1189
  else
1073
1190
  printf '\nRecover: npm install -g agent-bios@<older-version> && agent-bios install\n'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-bios",
3
- "version": "0.9.9",
4
- "releaseDate": "2026-07-26",
3
+ "version": "0.10.0",
4
+ "releaseDate": "2026-08-10",
5
5
  "description": "A thin, low-level instruction layer for LLM CLI agents: one set of principles and behavior whichever model you run. Deploys into $HOME by copy via an explicit `agent-bios install`.",
6
6
  "bin": {
7
7
  "agent-bios": "install.sh"
@@ -40,10 +40,14 @@
40
40
  "launch/provision-venv.sh",
41
41
  "session-cost.py",
42
42
  "README.md",
43
- "DEPENDENCIES.md"
43
+ "DEPENDENCIES.md",
44
+ "provenance.json"
44
45
  ],
45
46
  "scripts": {
46
- "postinstall": "printf '\\n> agent-bios installed. Deploy into this environment with: agent-bios install\\n> Then: agent-bios verify | status | uninstall\\n\\n'"
47
+ "postinstall": "printf '\\n> agent-bios installed. Deploy into this environment with: agent-bios install\\n> Then: agent-bios verify | status | uninstall\\n\\n'",
48
+ "prepack": "bash gates/check-publish.sh --stamp",
49
+ "prepublishOnly": "bash gates/check-publish.sh --guard",
50
+ "postpack": "rm -f provenance.json"
47
51
  },
48
52
  "publishConfig": {
49
53
  "access": "public"
@@ -0,0 +1 @@
1
+ {"commit":"2accbf670c653ecc3fcd8fa023cd33a8da7c177d","committedAt":"2026-08-10T06:03:23+09:00","dirty":false}