feat(plugin): a directory says which project it belongs to, git repo or not (#4085)
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 10s
CI & Build / integration (push) Successful in 47s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Failing after 1m1s
CI & Build / Build & push image (push) Skipped
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 10s
CI & Build / integration (push) Successful in 47s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / Python tests (push) Failing after 1m1s
CI & Build / Build & push image (push) Skipped
All six hooks scoped their requests one way: `git remote get-url origin`,
resolved server-side through the repo bindings. That key does not exist
outside a git repo, so a session in a plain directory was unscoped in every
hook at once — no project context, no prior-art scoping, no project rules —
and silently, because a missing remote is indistinguishable from a remote
nobody bound.
A `.scribe` file is the second key, read by the shared scribe_scope_query so a
directory scopes the same way everywhere:
{"instance": "https://scribe.example.com", "project_id": 2, "project": "…"}
`instance` is why the file is not just a number: an id is a different project
on every Scribe, so a marker that travels — a copied directory, a shared
machine, a repo someone else clones — would otherwise scope the session to the
wrong project without a word. Compared host-only, and a mismatch drops the id:
no project beats the wrong project. A bare integer is accepted too, since it
is what a person writes by hand. The marker beats a git remote — someone put
the file there on purpose — which is also how a directory overrides its
binding.
Two things it found on the way:
* An explicit project_id that did not resolve rendered NO message at all —
the branch hung off `if project_id` as an `elif`, so a caller holding a
pointer it believed in got a context that silently omitted the project it
had asked for. Now reported.
* The refusal reason was a global set inside a function every caller reads
through `$( )`. The assignment died with the subshell, leaving the caller
to read an unset variable under `set -u` — which aborts the hook and costs
the whole session's SessionStart context, to fetch a warning about a file.
It comes back through stdout with the id instead, and a test pins it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01821k5B3Ysecp9fNYs92Kuy
This commit is contained in:
@@ -13,10 +13,23 @@ asked for.
|
||||
|
||||
## Do this first (every session)
|
||||
|
||||
If the working repo maps to a Scribe project (you're in a known repo, or
|
||||
`list_repo_bindings` shows a binding), call `enter_project(id)` — it returns the
|
||||
project's goal, the milestones and open tasks worked on most recently, its
|
||||
Systems and the titles of its own rules in one shot.
|
||||
If the working directory maps to a Scribe project, call `enter_project(id)` —
|
||||
it returns the project's goal, the milestones and open tasks worked on most
|
||||
recently, its Systems and the titles of its own rules in one shot.
|
||||
|
||||
**A directory does not have to be a git repo to have a project.** A repo is
|
||||
bound by its remote (`list_repo_bindings` shows the bindings). Anything else —
|
||||
a notes folder, a server's config directory, a scratch directory — is bound by
|
||||
a `.scribe` file naming the project:
|
||||
|
||||
{"instance": "https://scribe.example.com", "project_id": 2, "project": "Homelab"}
|
||||
|
||||
`instance` is what makes the id trustworthy. An id means nothing on its own —
|
||||
it is a different project on every Scribe — so a marker that has travelled to
|
||||
another instance is ignored rather than followed to the wrong project. A bare
|
||||
`2` also works when writing the file by hand. When work plainly belongs to a
|
||||
project and the directory names none, offer to write the marker;
|
||||
`list_projects` has the id.
|
||||
|
||||
Then **ask before you act**: before anything hard to reverse or outward-facing,
|
||||
search the rules for what you are about to do. Reflex 2 below is why asking,
|
||||
|
||||
Reference in New Issue
Block a user