nawabari 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -11
- package/dist/cli.js +497 -92
- package/dist/cli.js.map +1 -1
- package/dist/contract.js +121 -2
- package/dist/contract.js.map +1 -1
- package/dist/domain/errors.d.ts +1 -1
- package/dist/domain/errors.js.map +1 -1
- package/dist/domain/session-backend.d.ts +5 -3
- package/dist/domain/session-backend.js +101 -4
- package/dist/domain/session-backend.js.map +1 -1
- package/dist/domain/session.d.ts +116 -2
- package/dist/domain/session.js +36 -0
- package/dist/domain/session.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/git.d.ts +62 -0
- package/dist/git.js +299 -0
- package/dist/git.js.map +1 -1
- package/dist/operation-authorization.d.ts +5 -2
- package/dist/operation-authorization.js +6 -7
- package/dist/operation-authorization.js.map +1 -1
- package/dist/output-budget.d.ts +16 -0
- package/dist/output-budget.js +58 -0
- package/dist/output-budget.js.map +1 -0
- package/dist/presentation.js +28 -4
- package/dist/presentation.js.map +1 -1
- package/dist/repository-evidence.d.ts +74 -0
- package/dist/repository-evidence.js +7 -0
- package/dist/repository-evidence.js.map +1 -0
- package/dist/resource-claims.d.ts +25 -3
- package/dist/resource-claims.js +57 -5
- package/dist/resource-claims.js.map +1 -1
- package/dist/session-registry.d.ts +43 -7
- package/dist/session-registry.js +375 -102
- package/dist/session-registry.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -64,6 +64,8 @@ The result schemas expose the following identities:
|
|
|
64
64
|
| claims | `claim_id`, `session_id`, `resource`, `mode` |
|
|
65
65
|
| authorization | `operation`, `allowed`, `code`, `claim_ids` |
|
|
66
66
|
| checkpoint evidence | `head`, `changed`, `staged`, `unstaged`, `untracked`, `in_claim`, `out_of_claim` |
|
|
67
|
+
| repository evidence | `session_id`, `base_revision`, `head`, `clean`, `paths.stats`, `evidence_hash` |
|
|
68
|
+
| bounded diff | `from_revision`, `to_revision`, `paths`, `stats`, `patch`, `evidence_hash` |
|
|
67
69
|
| commit/push | `commit_sha`, `remote`, `branch`, `target`, `relation` |
|
|
68
70
|
| reconciliation/cleanup | `clean`, `issues`, `candidates`, `cleaned`, `blocked`, `recovery_hints` |
|
|
69
71
|
|
|
@@ -74,6 +76,35 @@ The local lifecycle requires Git and the repository-local registry/lock only;
|
|
|
74
76
|
it does not require Mottainai, GitHub, `gh`, network access, an LLM, or a
|
|
75
77
|
coding-agent runtime.
|
|
76
78
|
|
|
79
|
+
## Read-only repository evidence
|
|
80
|
+
|
|
81
|
+
The evidence family is session-addressed and has no task, Issue, semantic, or
|
|
82
|
+
GitHub interpretation. It is the physical repository authority for one owned
|
|
83
|
+
session:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
git nawabari evidence snapshot --session "$NAWABARI_SESSION_ID" --json
|
|
87
|
+
git nawabari diff --session "$NAWABARI_SESSION_ID" --path src/example.ts --json
|
|
88
|
+
git nawabari diff --session "$NAWABARI_SESSION_ID" --path src/example.ts \
|
|
89
|
+
--patch --max-bytes 32768 --max-hunks 32 --json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`evidence snapshot` verifies the registry's repository/worktree/branch owner,
|
|
93
|
+
then reuses checkpoint's exact NUL-safe Git observation for `changed`,
|
|
94
|
+
`staged`, `unstaged`, and `untracked` paths. It also reports canonical per-path
|
|
95
|
+
stats, `clean`, the current `head`, session state, and an `evidence_hash`.
|
|
96
|
+
New sessions persist the exact creation/base revision as `base_revision`;
|
|
97
|
+
legacy records that lack this field report `base_revision: null` and
|
|
98
|
+
`base_revision_proven: false` rather than inferring it from a mutable ref.
|
|
99
|
+
|
|
100
|
+
`diff` requires at least one explicit concrete path and never accepts a glob or
|
|
101
|
+
an empty repository-wide selection. Stats are returned by default. Patch text
|
|
102
|
+
requires `--patch` and is bounded to at most 64 paths, 64 KiB, and 128 hunks;
|
|
103
|
+
the caller may request smaller limits. Unrepresentable Git observations fail
|
|
104
|
+
with `GIT_STATE_AMBIGUOUS`; a requested path whose stat is not exposed by Git
|
|
105
|
+
remains in the result with `available: false` and makes snapshot evidence
|
|
106
|
+
`complete: false`, so no path silently disappears.
|
|
107
|
+
|
|
77
108
|
## Session lifecycle
|
|
78
109
|
|
|
79
110
|
Session IDs are generated automatically as UUIDv7 values. They are immutable
|
|
@@ -91,6 +122,11 @@ git nawabari gc --dry-run --json
|
|
|
91
122
|
git nawabari doctor --json
|
|
92
123
|
```
|
|
93
124
|
|
|
125
|
+
`status --json` reports the resolved `managed_worktree_root` used when
|
|
126
|
+
`session create` omits `--worktree`. `session create --help --json` describes
|
|
127
|
+
all four create options as optional and reports defaults for branch, worktree,
|
|
128
|
+
base (`HEAD`), and label.
|
|
129
|
+
|
|
94
130
|
`session create` provisions a dedicated worktree and mutable branch atomically
|
|
95
131
|
under the repository-scoped mutation lock. The default/integration worktree
|
|
96
132
|
and its protected branch cannot be session resources. `session id` and the
|
|
@@ -108,6 +144,19 @@ every candidate that is not safe. Cleanup revalidates the physical worktree,
|
|
|
108
144
|
branch, and `HEAD` observations immediately before each destructive Git
|
|
109
145
|
operation.
|
|
110
146
|
|
|
147
|
+
Routine `session list` and `status` output excludes `closed` history and is
|
|
148
|
+
limited to 64 records. Use `--all` (or `--history`) for an explicit complete
|
|
149
|
+
history view; closed records remain persisted and are never silently deleted
|
|
150
|
+
by listing or cleanup.
|
|
151
|
+
|
|
152
|
+
`gc` stale eligibility is separate from closed-history retention. Its default
|
|
153
|
+
threshold is 24 hours (`86,400,000` ms), measured from persisted `updated_at`;
|
|
154
|
+
records already in `stale` or `closing` state are eligible, and an otherwise
|
|
155
|
+
live record is also eligible when Git reports its registered worktree as
|
|
156
|
+
missing or prunable. Physical Git/worktree state is authoritative for that
|
|
157
|
+
check. `gc --dry-run` and `gc --apply` do not treat a closed record as a stale
|
|
158
|
+
cleanup candidate.
|
|
159
|
+
|
|
111
160
|
`doctor` includes a non-destructive `reconciliation` check. It reports
|
|
112
161
|
registry/Git ownership drift, including missing or prunable worktrees and
|
|
113
162
|
unregistered physical worktrees, without repairing or deleting anything.
|
|
@@ -119,8 +168,10 @@ same repository registry and protected by the same mutation lock. They are
|
|
|
119
168
|
caller declarations; Nawabari does not infer them from task text or source
|
|
120
169
|
code. Claim JSON exposes `schema_version`, `claim_id`, `session_id`, the
|
|
121
170
|
repository/worktree identities, canonical `resource`, `mode`, and timestamps.
|
|
122
|
-
The
|
|
123
|
-
`exclusive-write`.
|
|
171
|
+
The claim schema version is `2` and supports `read`, `write`, and
|
|
172
|
+
`exclusive-write`. Schema v1 records use different overlap semantics and are
|
|
173
|
+
not interpreted implicitly: an embedding caller must explicitly run
|
|
174
|
+
`SessionRegistry.migrate()` before using them.
|
|
124
175
|
|
|
125
176
|
```bash
|
|
126
177
|
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
@@ -131,14 +182,23 @@ git nawabari session update --session "$NAWABARI_SESSION_ID" \
|
|
|
131
182
|
git nawabari session release --session "$NAWABARI_SESSION_ID" --json
|
|
132
183
|
```
|
|
133
184
|
|
|
185
|
+
The modes have these normative meanings:
|
|
186
|
+
|
|
187
|
+
- `read`: a non-mutating access declaration. It is not a consistency lease,
|
|
188
|
+
so it may overlap an ordinary `write` claim.
|
|
189
|
+
- `write`: ordinary source-modification authority. It may overlap `read`, but
|
|
190
|
+
not another writer or any `exclusive-write` claim.
|
|
191
|
+
- `exclusive-write`: stronger ownership-sensitive mutation authority. It
|
|
192
|
+
excludes every overlapping claim, including `read`.
|
|
193
|
+
|
|
134
194
|
Overlapping claims use this complete compatibility matrix; non-overlapping
|
|
135
195
|
claims are compatible for every mode:
|
|
136
196
|
|
|
137
|
-
| existing \/ requested | read | write
|
|
138
|
-
| --------------------- | ---------- |
|
|
139
|
-
| read | compatible |
|
|
140
|
-
| write |
|
|
141
|
-
| exclusive-write | conflict | conflict
|
|
197
|
+
| existing \/ requested | read | write | exclusive-write |
|
|
198
|
+
| --------------------- | ---------- | ---------- | --------------- |
|
|
199
|
+
| read | compatible | compatible | conflict |
|
|
200
|
+
| write | compatible | conflict | conflict |
|
|
201
|
+
| exclusive-write | conflict | conflict | conflict |
|
|
142
202
|
|
|
143
203
|
Claims use canonical repository-relative POSIX paths. Literal path segments,
|
|
144
204
|
`*`/`?` segment wildcards, and a complete `**` segment are supported. Empty,
|
|
@@ -149,6 +209,26 @@ garbage-collecting a session releases its claims; no separate claim registry
|
|
|
149
209
|
or claim lock exists. Claims describe ownership state only and do not provide
|
|
150
210
|
OS-level filesystem observation or a filesystem sandbox.
|
|
151
211
|
|
|
212
|
+
An ordinary source change uses `write` and can proceed while another session
|
|
213
|
+
holds a `read` declaration:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
217
|
+
--resource src/example.ts --mode write --json
|
|
218
|
+
git nawabari authorize --session "$NAWABARI_SESSION_ID" \
|
|
219
|
+
--operation source-write --resource src/example.ts --json
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
A stronger ownership-sensitive operation uses `exclusive-write` and therefore
|
|
223
|
+
requires no overlapping claim:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
git nawabari session claim --session "$NAWABARI_SESSION_ID" \
|
|
227
|
+
--resource src/example.ts --mode exclusive-write --json
|
|
228
|
+
git nawabari authorize --session "$NAWABARI_SESSION_ID" \
|
|
229
|
+
--operation commit --resource src/example.ts --json
|
|
230
|
+
```
|
|
231
|
+
|
|
152
232
|
## Ownership guard
|
|
153
233
|
|
|
154
234
|
`git nawabari guard` is a cheap, side-effect-free authorization decision for a
|
|
@@ -217,9 +297,15 @@ repository-relative resources. Nawabari independently verifies the current
|
|
|
217
297
|
repository, owned worktree, branch, active session, and persisted claims;
|
|
218
298
|
caller-supplied labels do not weaken that decision. The JSON result is the
|
|
219
299
|
automation contract and reports stable allow/deny codes such as
|
|
220
|
-
`MISSING_RESOURCE_CLAIM`, `
|
|
300
|
+
`MISSING_RESOURCE_CLAIM`, `INSUFFICIENT_CLAIM_MODE`, `RESOURCE_CLAIM_CONFLICT`,
|
|
301
|
+
`INVALID_RESOURCE`, and
|
|
221
302
|
the existing ownership/physical-observation codes.
|
|
222
303
|
|
|
304
|
+
`INSUFFICIENT_CLAIM_MODE` means a matching claim exists but its granted mode
|
|
305
|
+
is weaker than the operation requires. Its bounded details identify the
|
|
306
|
+
resource, required access, and matching granted mode names;
|
|
307
|
+
`MISSING_RESOURCE_CLAIM` remains reserved for an absent matching claim.
|
|
308
|
+
|
|
223
309
|
**`authorize` returns an authorization decision only; it does NOT execute the
|
|
224
310
|
operation itself.** Governed commit and push execution use this same decision
|
|
225
311
|
path before invoking bounded Git subprocesses.
|
|
@@ -234,17 +320,51 @@ repository-relative resources. Every resource must be covered by an active
|
|
|
234
320
|
`exclusive-write` claim; all Git-visible changed/staged paths must be in the
|
|
235
321
|
explicit list. JSON includes the resulting `commit_sha`.
|
|
236
322
|
|
|
323
|
+
Commit evidence distinguishes three sets: the caller's **declared/authorized**
|
|
324
|
+
resources (the explicit, claim-covered list a caller passed in), the
|
|
325
|
+
**staged** set Git reports as staged immediately before the commit runs, and
|
|
326
|
+
the **actual committed** set — read back from the resulting commit itself via
|
|
327
|
+
a bounded, NUL-safe `git diff-tree` observation, not inferred from staging
|
|
328
|
+
intent. The `resources` field in a successful `commit --json` result is
|
|
329
|
+
always the actual committed set, proven equal to or a subset of the
|
|
330
|
+
authorized resources; if Git staging/index drift between staging and the
|
|
331
|
+
commit (a hook, a concurrent process) causes the actual commit to contain a
|
|
332
|
+
path outside the authorized set, the result is not reported as an ordinary
|
|
333
|
+
successful commit — it fails with `COMMIT_RESULT_DIVERGED`, which retains the
|
|
334
|
+
resulting `commitSha` (the Git commit already happened) alongside the
|
|
335
|
+
authorized, actual, and divergent path sets for recovery/reconciliation.
|
|
336
|
+
|
|
237
337
|
```bash
|
|
238
338
|
git nawabari commit --session "$NAWABARI_SESSION_ID" \
|
|
239
339
|
--message 'record the local change' --resource src/example.ts --json
|
|
240
340
|
```
|
|
241
341
|
|
|
342
|
+
An optional `--message-pattern <regex>` validates the final message against a
|
|
343
|
+
caller-declared rule before Git is invoked; Nawabari does not own or infer
|
|
344
|
+
commit-message conventions (such as Conventional Commits) itself, so this
|
|
345
|
+
check runs only when a caller explicitly supplies a pattern, and a mismatch
|
|
346
|
+
fails with `INVALID_COMMIT_MESSAGE` before anything is staged. The pattern is
|
|
347
|
+
bounded to 512 characters and is evaluated before the repository lock is
|
|
348
|
+
acquired, so a pathological caller-supplied pattern cannot stall other
|
|
349
|
+
sessions' governed operations. A repository's own `commit-msg` Git hook (if
|
|
350
|
+
any) still runs normally, since governed commit invokes real `git commit`.
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
git nawabari commit --session "$NAWABARI_SESSION_ID" \
|
|
354
|
+
--message 'feat: record the local change' --resource src/example.ts \
|
|
355
|
+
--message-pattern '^(feat|fix|docs|refactor|test|chore): .+$' --json
|
|
356
|
+
```
|
|
357
|
+
|
|
242
358
|
Governed push requires explicit claim-covered resources and an explicit
|
|
243
359
|
`--remote`/`--branch` target. Existing upstream and local/remote relation are
|
|
244
360
|
inspected before mutation. A missing upstream requires `--create-upstream`;
|
|
245
|
-
behind or diverged history requires explicit `--force
|
|
246
|
-
`--force-with-lease
|
|
247
|
-
|
|
361
|
+
behind or diverged history requires explicit `--force`. Force pushes use an
|
|
362
|
+
exact `--force-with-lease` bound to the observed remote branch SHA; non-force
|
|
363
|
+
pushes rely on `--no-force` without any lease option. Nawabari fetches only
|
|
364
|
+
the explicit remote branch into a disposable ref when local ancestry is
|
|
365
|
+
missing; it does not update tracking refs or fetch unrelated branches/tags.
|
|
366
|
+
The JSON result includes the immutable `source_sha`, explicit `target_ref`,
|
|
367
|
+
observed `observed_remote_sha`, and relation.
|
|
248
368
|
|
|
249
369
|
```bash
|
|
250
370
|
git nawabari push --session "$NAWABARI_SESSION_ID" \
|
|
@@ -259,6 +379,15 @@ filesystem activity that is reverted, ignored, or otherwise not observable in
|
|
|
259
379
|
the Git checkpoint is outside Nawabari's guarantee; this feature is not an
|
|
260
380
|
OS-level filesystem monitor.
|
|
261
381
|
|
|
382
|
+
Checkpoint canonicalization fails closed: a Git-reported path that cannot be
|
|
383
|
+
represented as a canonical repository resource (traversal, symlink escape, or
|
|
384
|
+
syntax reserved for the claim/glob model) never disappears from evidence.
|
|
385
|
+
Checkpoint fails the whole observation with `GIT_STATE_AMBIGUOUS` instead of
|
|
386
|
+
silently omitting the path, so a caller can never mistake an unrepresentable
|
|
387
|
+
observation for a clean one. This mirrors the strictness governed mutation
|
|
388
|
+
already applies to the same Git-observed paths, so checkpoint evidence is
|
|
389
|
+
never weaker than mutation authorization.
|
|
390
|
+
|
|
262
391
|
## Physical execution context
|
|
263
392
|
|
|
264
393
|
Nawabari treats Git and the canonical filesystem as the authority for every
|
|
@@ -280,6 +409,11 @@ worktree paths, and existing local branches are rejected deterministically;
|
|
|
280
409
|
the repository lock serializes Nawabari provisioning and Git's own ref checks
|
|
281
410
|
remain the final collision authority.
|
|
282
411
|
|
|
412
|
+
An explicit `--base` ref that is empty, malformed, or does not resolve to a
|
|
413
|
+
commit fails with `INVALID_BASE_REF`. The bounded JSON details retain the
|
|
414
|
+
rejected ref, identify `HEAD` as the default recovery base, and include the
|
|
415
|
+
retry hint to omit `--base`; Nawabari does not enumerate or fuzzy-search refs.
|
|
416
|
+
|
|
283
417
|
## Repository state and concurrency
|
|
284
418
|
|
|
285
419
|
The authoritative registry is stored in the repository-common Git directory at
|