Skip to content

Docs/walkthrough complete - #7

Merged
Anuragp22 merged 9 commits into
masterfrom
docs/walkthrough-complete
Jul 31, 2026
Merged

Docs/walkthrough complete#7
Anuragp22 merged 9 commits into
masterfrom
docs/walkthrough-complete

Conversation

@Anuragp22

Copy link
Copy Markdown
Owner

No description provided.

The page explained how a graph is built and how a diff is analysed, but
never showed what you actually type, and gave no stage at all to five
shipped capabilities. Anyone reading it would have concluded those did
not exist.

Adds Act I — what it is (7 stages): the two commands and their real
output, the anatomy of graph.json, how to read a result row, then a
stage each for why, hotspots, report + serve, and configuration.

Adds an incremental-indexing stage to Act II: sha256 per file, what is
cached (parsing) and what deliberately is not (the graph itself, because
one changed file can alter which definition a call in an untouched file
resolves to).

28 stages across four acts. Every figure re-measured against a cold
re-index at ad6c837: 662 nodes, 1,483 edges, 23.4% of call sites
resolved, 6 of 494 functions rated HIGH.

Three limitations found while writing it, now stated on the page:

  - hotspots ignores confidence entirely, so the top result on this repo
    is Error with 47 inbound edges — all of them heuristic mis-resolutions
  - the hotspots CLI help describes the score as "inbound × outbound";
    the code computes inbound*2 + outbound, and its comment explains why
    a product would be wrong
  - config values only override when non-zero, so a threshold of zero is
    unreachable, and the risk thresholds have no CLI flags at all

Also fixes 19 places where htm glued a word to a following bold or code
run ("produces662 nodes") by stripping the newline between them.
Two problems with the walkthrough as a thing you present live.

It fetched React, Framer Motion and htm from esm.sh at load time, so a
blocked CDN or flaky wifi replaced the page with its own error screen.
They are now bundled by esbuild into docs/vendor/deps.js and imported
from disk — verified by clicking through all 33 stages with every
non-localhost request aborted: zero external requests, zero console
errors. motion-dom and motion-utils are pinned, because Framer Motion
12.23.12 imports activeAnimations and later 12.x releases drop it.

The .gitignore change is part of that fix: an unanchored `vendor/` rule
meant for Go's root vendor directory also matched docs/vendor/, so the
bundle would never have been committed and a fresh clone would have
served a page with no runtime. Anchored to /vendor/.

The second problem: the page explained the pipeline without ever showing
the system's shape. Adds Act II — architecture, derived from the
production imports of every Go file rather than drawn by hand:

  - package map: 11 packages in 5 layers, dependencies pointing one way,
    cycle check clean
  - the seams: FileResult, GraphData, AnalysisResult — plain structs, no
    interfaces, which is why parsers and output surfaces are swappable
  - the cycle: ownership imports analyzer, so analyzer cannot import
    ownership back. AnalysisResult.Ownership is interface{} with a
    runtime assertion in every consumer to break it — the layering is
    bought with a type hole, and the page says so
  - one run end to end: the ten calls an analyze makes across packages
  - decisions from bugs: eight commits where a defect became an
    invariant, each expandable for the reasoning

33 stages across five acts.
Three things were wrong with the page as a thing you talk over.

The hero never changed. The same headline and the same paragraph sat
above all 33 stages, so nothing on screen told you where in the story
you were. Each act now carries its own headline and thesis, cross-faded
on switch.

There was no sense of the whole. Added a spine under the hero: the tool
as eight blocks — source files, parse, graph.json, your diff, blast
radius, rank, surfaces, exit code — with the block belonging to the
current stage lit, and a marker that slides between them. Every stage
declares which block it belongs to, so the spine is a running answer to
"where are we". The architecture act lights all eight, because it is
talking about the whole system rather than a step in it.

The architecture "diagram" was chips in rows. It is now an actual block
diagram: ten boxes positioned by layer, seven arrows pointing from
dependent to dependency, leaves outlined in the exact-resolution colour
and analyzer highlighted as the one package everything converges on.
The seams stage gets a data-flow diagram of the three structs.

Also fixes a units bug the new hero exposed. The strip reported 18% of
call sites resolved while the resolve stage said 23.4%: resolvedPct was
dividing G.calls, a deduped edge count, by a call-site count. Both now
read 23.4% because both divide resolved sites by total sites.
The stage listed eight commits as "was X, now Y" with the old behaviour
struck through. The content was right and the framing was wrong: a
reader arrives at a defect log rather than a specification, and the
strongest material on the page reads as an apology.

Same eight properties, stated as invariants. Each gives the rule, why
it holds, the failure mode if it lapses, and the line that enforces it —
which is what an architecture document is for. The reasoning is
unchanged and nothing is hidden; a reader still learns that counting
call edges to get caller counts is wrong, and why.

Also softened three other places where the register slipped from
measured to self-deprecating: the scoring constants are an unfitted
prior rather than "a guess that has never been fitted", stated
limitations are scope boundaries rather than a disclaimer, and the
figure-revision note reads as provenance rather than confession.
The hero occupied a full viewport. Every stage change meant scrolling
past the same headline, thesis, stat strip and glossary before reaching
the content — on a 768px laptop the stage panel started below the fold.

The page is now a fixed shell. Chrome is a 56px header plus a compact
context bar carrying the act title, its thesis, the stat line and the
spine; the content area scrolls on its own, so switching stages never
moves the viewport. The glossary moved from a block in the flow to a
drawer on Escape or click-away. The act heading and rail label were
removed as duplicates of the context bar.

Chrome adapts to viewport height, because presentation screens are
short: below 850px the thesis and spine captions are dropped, below
720px the spine goes too.

  1920x1080   219px chrome (20%)
  1440x900    219px         (24%)
  1366x768    167px         (22%)
  1280x720    160px         (22%)

The stage mechanism is fully visible on load at every one of those.

Two bugs found while measuring. The scroll container was .panel, which
had no height constraint and overflowed its grid parent with no
scrollbar — everything past the fold was clipped and unreachable; the
container is now .layout. And the short-viewport rules sat above the
base rules they were meant to override, so at equal specificity the base
rules won and nothing compacted; they now come last in the sheet.
Six things the page listed as known problems. Five were small enough
that documenting them was the wrong choice.

Stale graphs no longer produce confident nonsense. A graph built at
another revision has drifted line numbers, so the diff maps onto
whatever now occupies them — an answer indistinguishable from a correct
one. This was a warning on stderr, which in CI scrolls past unread. It
now returns exit code 3: not "your change is risky" but "the tool cannot
stand behind this answer". --allow-stale is there when the drift is
known not to matter.

The report goes to stdout. It was written to stderr, so
`tracescope analyze > review.txt` produced an empty file. Progress
lines, warnings and the ambiguous-name helper stay on stderr, which is
what keeps a redirected report clean.

Config keys are read with pointers, so a key written in the file is
distinguishable from one left out. Previously only non-zero values
merged, so `max_depth: 0` was discarded in silence. Out-of-range values
are now named in a warning rather than ignored, and `top: 0` — the one
place zero is meaningful — is honoured.

FileMetadata loses ParsedAt. It was stamped on every index and read
nowhere, so two indexes of identical source produced different
graph.json bytes.

The terminal labels its two caller counts distinctly. It printed raw
fan-in as "callers" beside a reason quoting production callers: two
numbers, one word, same line.

The hotspots help text describes the formula the code implements. It
claimed inbound × outbound; the code computes inbound*2 + outbound, and
its comment explains why a product would bury pure sinks.

Verified end to end: a redirected report captures 245 lines with an
empty stderr; a graph stamped with a foreign sha exits 3 with a message
naming both revisions; --allow-stale then exits 2 as it should.

The walkthrough's limitation text is updated to match. What remains on
those six stages are genuine trade-offs rather than unfixed defects.
Three problems, all of them in how the page reads rather than what it
claims.

It described the system two different ways and never joined them up. The
strip at the top named eight pipeline stages; the architecture act named
eleven Go packages; nothing mapped one onto the other, so a reader had
to do it themselves. Act I now opens with a single diagram carrying
every part: what you give it, the two commands, the file between them,
and everything that comes out. The package diagram follows it as the
same system seen as code.

Seven of the thirty-three stages were the same material twice. The final
act was Acts III and IV again in more detail: front ends repeated the
parse stage, symbols repeated resolve, traversal repeated walk, the
formula repeated ranking. Those are folded into the stages they belong
to. Twenty-five stages now, in four acts, with nothing dropped.

The prose was doing too much work for the reader. 171 em dashes, plus
words like orthogonal, provenance, invariant, escape hatch, saturates
and sublinear where ordinary ones would do. Reader-facing prose now has
none of either. Swapping the punctuation mechanically produced comma
splices and sentence fragments, so the sentences were rewritten instead.

Acts are now: the system, indexing, analysing, checking. Architecture
comes first because that is what someone opening it wants.

Verified: 25/25 stages, no console errors, still runs from file:// with
the network off.
The walkthrough was a file in docs/, which is the wrong shape for its
actual job: a link in the README that a recruiter or a tech lead clicks.
It now builds into web/public/how-it-works.html, which Next.js serves
statically, so it goes live on the Vercel deployment at
/how-it-works.html with no routing, no build config and no porting to
React. The same file still opens straight from disk with no server and
no network, so both uses are covered by one artifact.

Act I now opens on the architecture map rather than on the two commands.
Someone landing cold wants the shape of the system first: ten boxes,
nine arrows, every part of the tool and the only paths data takes
between them. The commands follow as the second step.

The duplicate copy under docs/ is gone. docs/tracescope-motion.html
remains the source, and web/public/README.md documents how to rebuild
the standalone from it, including why both replacements have to pass a
function rather than a string.

The README link is a placeholder until the app is actually deployed.
No Vercel project is linked to this repository yet, so a real-looking
URL would have been a dead link on the front page.
The walkthrough was a static file in web/public, which Next serves
verbatim without compiling. That put it permanently outside the
component system: no shadcn, no shared theme, and a navigation rail
that could not be collapsed because it was hand-rolled CSS. It is now
a real route at /how-it-works.

The first screen is the architecture diagram and nothing else. It
previously sat sixth down the page at about half width, behind a hero
question, a five-figure stat line, a second diagram strip and three
lines of stage text. The reasoning and the stated limitation for that
stage moved below the fold rather than being dropped.

Navigation is the shadcn Sidebar, so it collapses from the header
button, from the rail, or with ctrl-B, and the choice persists in a
cookie. On narrow viewports it becomes a sheet instead of the
horizontal scroller it used to turn into. Figures are Cards, the
backend and scenario pickers are Tabs, citations are Badges, and the
glossary is a Sheet.

The provenance note used to render inside the panel, so its four
paragraphs repeated under all 25 stages. It now appears once, at the
end.

shadcn was configured here but not usable: components.json and the
theme tokens existed while lib/utils.ts, clsx, class-variance-authority
and the radix primitives did not. Those are installed, and the twelve
components the walkthrough uses are added.

Dashboard pages move into an (dashboard) route group so the walkthrough
is not nested inside the dashboard chrome. URLs are unchanged.

Two figures were wrong in the old page and are corrected here: the git
HEAD chip read an undefined field and rendered blank, and the resolved
percentage divided an edge count by a call-site count.

Verified in Chrome against a production build: 25 stages swept, every
one renders its figure and its limitation, no stage overflows
horizontally, the sidebar measures 256px collapsed to 0 and back, and
the console is clean.
@Anuragp22
Anuragp22 merged commit ce115d7 into master Jul 31, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant